我们正在构建一个分布式系统,该系统使用亚马逊的SQS根据消息向运行scrapy蜘蛛的工作人员发送消息。内容。
我们(显然)只想在成功运行相应的蜘蛛时从队列中删除消息,即不会遇到4xx / 5xx响应。
我想做的是加入scrapy的signals
API,以便在蜘蛛成功关闭时触发从队列中删除消息的回调,但我&# 39;我不确定这是否真的是signals.spider_closed
的语义(而不是#34;这个蜘蛛因字面上的任何原因而关闭。")
在遇到HTTP错误代码时,或者只有在蜘蛛内部引发Python错误时,是否也会发现signals.spider_error
是不明白的(至少对我而言)。
有什么建议吗?
答案 0 :(得分:0)
signals.spider_error
。如果spider_closed
信号处理程序中发生错误,则不会引发spider_error
。
一种基本方法是拥有一个信号处理程序扩展,它将注册到spider_closed
和spider_error
事件来处理状态 - 如果URL包含状态,请不要从队列中删除URL例如,高于399。
然后在这些处理程序方法中,您可以利用蜘蛛收集的统计数据来查看它是否正常:
class SignalHandler(object):
@classmethod
def from_crawler(cls,crawler):
ext = cls()
crawler.signals.connect(ext.spider_error, signal=signals.spider_error)
crawler.signals.connect(ext.spider_closed, signal=signals.spider_closed)
return ext
def spider_error(self, failure, response, spider):
print "Error on {0}, traceback: {1}".format(response.url, failure.getTraceback())
def spider_closed(self, spider):
if spider.crawler.stats.get_value('downloader/response_status_count/200') == spider.crawler.stats.get_value('downloader/response_count'):
# OK, all went fine
if spider.crawler.stats.get_value('downloader/response_status_count/404') != 0 or spider.crawler.stats.get_value('downloader/response_status_count/503') != 0:
# something went wrong
当然不要忘记在SignalHandler
中添加settings.py
:
EXTENSIONS = {'myproject.extensions.signal_handler.SignalHandler': 599,}
当然还有另一种方法需要更多编码:
您可以使用蜘蛛的handle_httpstatus_list
参数自行处理状态代码。这允许您的蜘蛛处理HTTP状态列表,默认情况下将忽略该列表。
总结一种方法是处理您对蜘蛛感兴趣的状态并将其收集到set
。
这将是蜘蛛:
class SomeSpider(scrapy.Spider):
name = "somespider"
start_urls = {"http://stackoverflow.com/questions/25308231/liferay-6-2-lar-import-no-journalfolder-exists-with-the-primary-key-2"}
handle_httpstatus_list = [404, 503]
encountered = set()
def parse(self, response):
self.encountered.add(response.status)
# parse the response
这将是扩展程序的新方法:
def spider_closed(self, spider):
if 404 in spider.encountered:
# handle 404