经过几个小时的修补和尝试片段后,我发现在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
。
我该如何解决这个问题?
答案 0 :(得分:2)
请注意,您的程序在两个地方调用reactor.run
- 其中一个地方被重复调用,有效地在循环中调用(因为LoopingCall
(间接)调用它)。
Twisted的反应堆无法重启。你可以运行和停止一次。如果您尝试再次运行它们,那么您将获得一个例外。如果你试图在它们运行时运行它们,那么你会得到另一个例外 - ReactorAlreadyRunning
- 如你所见。
这里的解决方案是仅运行一次反应器。因此,您也应该只停止反应堆一次。
至少,这意味着您只能从程序中的某个位置拨打reactor.run
。我建议,作为一个开始,程序最后的调用是你要保留的调用,run
方法中的调用(每次运行蜘蛛时调用一次)应该是消除。
蜘蛛完成后,您还需要避免停止反应堆。如果您将reactor.stop
连接到spider_done
,那么在蜘蛛第一次运行后反应堆将停止并且您将无法再次运行蜘蛛。我想你可以简单地删除你程序的这一部分。