2

经过几个小时的修补和尝试代码片段,我在stackoverflow中发现,我终于设法定期运行scrapy:

timeout = 60.0 # seconds

class UrlCrawlerScript(Process):
    def __init__(self, spider):
        Process.__init__(self)
        settings = get_project_settings()
        self.crawler = Crawler(settings)

        if not hasattr(project, 'crawler'):
            self.crawler.install()
            self.crawler.configure()
            self.crawler.signals.connect(reactor.stop, signal=signals.spider_closed)
        self.spider = spider

    def run(self):
        self.crawler.crawl(self.spider)
        self.crawler.start()
        reactor.run()


def run_spider():
    spider = MarketSpider()
    crawler = UrlCrawlerScript(spider)
    crawler.start()
    crawler.join()
    print 'finished'


l = task.LoopingCall(run_spider)
l.start(timeout) # call every sixty seconds

reactor.run()

我的问题是,ReactorAlreadyRunning第二次运行后我仍然得到。我怎样才能解决这个问题?

4

1 回答 1

3

请注意,您的程序reactor.run在两个地方调用 - 其中一个地方被重复调用,有效地循环调用(因为它是由 (间接)调用的LoopingCall)。

Twisted 的反应堆不可重启。您可以运行和停止它们一次。如果您尝试再次运行它们,则会出现异常。如果您尝试在它们运行时运行它们,那么您会遇到另一个异常ReactorAlreadyRunning- 正如您所看到的。

这里的解决方案是只运行一次反应器。因此,您也应该只停止反应器一次。

至少,这意味着您应该只reactor.run从程序中的一个地方调用。我建议,作为开始,程序最后的调用是您想要保留的调用,而方法内部的run调用(每次运行蜘蛛时都会调用一次)应该被删除。

您还需要避免在蜘蛛完成后停止反应器。如果您在蜘蛛第一次运行后连接reactor.stopspider_donethen,反应器将停止,您将无法再次运行蜘蛛。我认为您可以简单地删除程序的这一部分。

于 2014-08-31T14:55:25.210 回答