我已经实现了一个依靠Scrapy同时运行多个蜘蛛的解决方案。根据我在这里阅读的内容(http://doc.scrapy.org/en/latest/topics/exceptions.html),为了优先发信号通知蜘蛛是时候死了,我应该按如下方式提出一个CloseSpider异常:
from scrapy.exceptions import CloseSpider
class SomeSpider(CrawlSpider):
def parse_items(self, response):
if self.to_be_killed:
raise CloseSpider(reason="Received kill signal")
但是,虽然代码在遇到异常时似乎确实引发了异常,但蜘蛛仍在长时间处理请求。我需要它立即停止它正在做的事情。
我意识到Scrapy是围绕异步框架构建的,但有没有办法可以强制蜘蛛关闭而不会产生任何额外的出站请求?
答案 0 :(得分:6)
所以我最终使用了一个hacky解决方案来绕过这个问题。 我写下DownloaderMiddleware而不是实际上以一种与Twisted框架不能很好地结合的方式立即终止蜘蛛,而是拒绝任何来自我请求关闭的蜘蛛的请求。
所以:
from scrapy import log
from scrapy.exceptions import IgnoreRequest
class SpiderStatusMiddleware:
def process_request(self, request, spider):
if spider.to_be_killed or not spider.active:
log.msg("Spider has been killed, ignoring request to %s" % request.url, log.DEBUG, spider=spider)
raise IgnoreRequest()
return None
注意:to_be_killed和active都是我在我的蜘蛛类中定义的标志,并且由我自己的代码管理。