我已阅读here和here,并让多个蜘蛛在同一个流程中运行。
然而,我不知道如何设计一个信号系统来在所有蜘蛛完成后停止反应堆
我的代码与以下示例非常相似:
from twisted.internet import reactor
from scrapy.crawler import Crawler
from scrapy.settings import Settings
from scrapy import log
from testspiders.spiders.followall import FollowAllSpider
def setup_crawler(domain):
spider = FollowAllSpider(domain=domain)
crawler = Crawler(Settings())
crawler.configure()
crawler.crawl(spider)
crawler.start()
for domain in ['scrapinghub.com', 'insophia.com']:
setup_crawler(domain)
log.start()
reactor.run()
在所有爬行器停止后,反应堆仍在运行。 如果我添加声明
crawler.signals.connect(reactor.stop, signal=signals.spider_closed)
到setup_crawler函数,当第一个爬虫关闭时,reactor停止。
当所有履带式装载机完成后,是否可以向我展示如何使反应堆停止?
答案 0 :(得分:2)
除了shackra的回答,采取这条路线确实有效。您可以将信号接收器创建为保留状态的闭包,这意味着它会记录已完成的蜘蛛数量。您的代码应该知道您正在运行多少蜘蛛,因此检查所有蜘蛛运行的时间应该是一个简单的问题,然后运行reactor.stop()
。
e.g
将信号接收器链接到您的爬虫:
crawler.signals.connect(spider_finished, signal=signals.spider_closed)
创建信号接收器:
def spider_finished_count():
spider_finished_count.count = 0
def inc_count(spider, reason):
spider_finished_count.count += 1
if spider_finished_count.count == NUMBER_OF_SPIDERS:
reactor.stop()
return inc_count
spider_finished = spider_finished_count()
NUMBER_OF_SPIDERS是您在此过程中运行的蜘蛛总数。
或者你可以反过来做,并从蜘蛛的数量减少到0倒计数。或者更复杂的解决方案可能涉及保持一个蜘蛛有没有完成的字典等。
注意:inc_count被发送spider
和reason
我们在这个例子中没有使用,但你可能希望使用这些变量:它们是从信号调度员发送的,是关闭的蜘蛛结束的原因(str)。
Scrapy版本:v0.24.5
答案 1 :(得分:1)
我通常在PySide(我使用QNetworkAccessManager
和许多自己创建的工作人员进行报废)的工作是保留一个计数器,表明有多少工人从队列中完成处理工作,当此计数器达到创建工作程序时,会触发一个信号,指示没有其他工作要做,应用程序可以执行其他操作(例如启用" export" 按钮,以便用户可以将其导出#39; s对文件的结果等)。当然,这个计数器必须在一个方法中,并且必须在爬虫/蜘蛛/工人发出信号时调用。
这可能不是一种解决问题的优雅方法,但是,你有没有试过这个?