我们正在构建一个分布式系统,它使用Amazon的SQS将消息分派给根据消息内容运行爬虫的工作者。
我们(显然)只希望在相应的爬行器成功运行的情况下从队列中删除消息,即不会遇到4xx/5xx响应。
我想要做的是挂钩到scrapy的signals
API来触发一个回调,当爬虫成功关闭时,该回调将从队列中删除消息,但我不确定这是否真的是signals.spider_closed
的语义(而不是“这个蜘蛛由于任何原因而关闭”)。
也不清楚(至少对我而言) signals.spider_error
是在遇到HTTP错误代码时触发,还是仅在爬行器中引发Python错误时触发。
有什么建议吗?
发布于 2015-08-28 14:35:46
在爬网过程中发生Python错误时,将引发signals.spider_error
。如果错误发生在spider_closed
信号处理程序中,则不会引发spider_error
。
一种基本方法是有一个信号处理程序扩展,它将注册到spider_closed
和spider_error
事件来处理状态--例如,如果它包含的状态高于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
当然,不要忘记在settings.py
中添加您的SignalHandler
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
https://stackoverflow.com/questions/32257330
复制相似问题