经过几个小时的修补和尝试代码片段后,我在 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
。
我该如何解决这个问题?
最佳答案
请注意,您的程序在两个位置调用 reactor.run
- 其中一个位置被重复调用,有效地在循环中(因为它是由 LoopingCall(间接)调用的)
).
Twisted 的 react 堆不可重启。您可以运行并阻止它们一次。如果您尝试再次运行它们,则会出现异常。如果您尝试在它们运行时运行它们,那么您会收到另一个异常 - ReactorAlreadyRunning
- 正如您所看到的。
这里的解决方案是仅运行 react 器一次。因此,您也应该只停止 react 堆一次。
这至少意味着您应该只从程序中的一处调用 reactor.run
。我建议,作为一开始,程序最后的调用是您想要保留的调用,并且是 run
方法中的调用(每次运行蜘蛛时都会调用一次) )应该被消除。
您还需要避免在蜘蛛完成后停止 react 堆。如果您将 reactor.stop
连接到 spider_done
,那么在蜘蛛第一次运行后, react 器将停止,您将无法再次运行蜘蛛。我认为你可以简单地删除程序的这一部分。
关于python - 从 python 中定期运行 Scrapy 会导致 ReactorAlreadyRunning,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25588015/