如何在几个scrapy蜘蛛在同一过程中运行时停止反应堆

时间:2013-09-13 13:37:02

标签: python web-crawler scrapy

我已阅读herehere,并让多个蜘蛛在同一个流程中运行。

然而,我不知道如何设计一个信号系统来在所有蜘蛛完成后停止反应堆

我的代码与以下示例非常相似:

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停止。

当所有履带式装载机完成后,是否可以向我展示如何使反应堆停止?

2 个答案:

答案 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被发送spiderreason我们在这个例子中没有使用,但你可能希望使用这些变量:它们是从信号调度员发送的,是关闭的蜘蛛结束的原因(str)。

Scrapy版本:v0.24.5

答案 1 :(得分:1)

我通常在PySide(我使用QNetworkAccessManager和许多自己创建的工作人员进行报废)的工作是保留一个计数器,表明有多少工人从队列中完成处理工作,当此计数器达到创建工作程序时,会触发一个信号,指示没有其他工作要做,应用程序可以执行其他操作(例如启用" export" 按钮,以便用户可以将其导出#39; s对文件的结果等)。当然,这个计数器必须在一个方法中,并且必须在爬虫/蜘蛛/工人发出信号时调用。

这可能不是一种解决问题的优雅方法,但是,你有没有试过这个?