在Python中运行Scrapy任务

时间:2011-11-03 10:55:32

标签: python scrapy

当我在命令行的“一次性”场景中运行时,我的Scrapy脚本似乎工作正常,但如果我尝试在同一个python会话中运行代码两次,我会收到此错误:

“ReactorNotRestartable”

为什么?

违规代码(最后一行抛出错误):

crawler = CrawlerProcess(settings)
crawler.install()
crawler.configure()

# schedule spider
#crawler.crawl(MySpider())
spider = MySpider()
crawler.queue.append_spider(spider)

# start engine scrapy/twisted
crawler.start()

4 个答案:

答案 0 :(得分:11)

接近Joël的答案,但我想在评论中详细说明。如果您查看Crawler source code,就会发现CrawlerProcess类有一个start,还有一个stop函数。此stop函数负责清理爬网内部,以便系统最终处于可以重新启动的状态。

因此,如果您想在不离开流程的情况下重新启动抓取,请在适当的时候致电crawler.stop()。稍后,只需再次致电crawler.start()即可恢复运营。

编辑:回想起来,这是不可能的(由于Twisted反应堆,如另一个答案所述); stop只是照顾干净的终止。回顾我的代码,我碰巧有一个Crawler进程的包装器。下面你可以找到一些(编辑过的)代码,使它可以使用Python的多处理模块。通过这种方式,您可以更轻松地重新启动爬虫。 (注意:我上个月在网上找到了代码,但是我没有包含来源......所以如果有人知道它来自哪里,我会更新来源的信用。)

from scrapy import project, signals
from scrapy.conf import settings
from scrapy.crawler import CrawlerProcess
from scrapy.xlib.pydispatch import dispatcher
from multiprocessing.queues import Queue
from multiprocessing import Process

class CrawlerWorker(Process):
    def __init__(self, spider, results):
        Process.__init__(self)
        self.results = results

        self.crawler = CrawlerProcess(settings)
        if not hasattr(project, 'crawler'):
            self.crawler.install()
        self.crawler.configure()

        self.items = []
        self.spider = spider
        dispatcher.connect(self._item_passed, signals.item_passed)

    def _item_passed(self, item):
        self.items.append(item)

    def run(self):
        self.crawler.crawl(self.spider)
        self.crawler.start()
        self.crawler.stop()
        self.results.put(self.items)

# The part below can be called as often as you want
results = Queue()
crawler = CrawlerWorker(MySpider(myArgs), results)
crawler.start()
for item in results.get():
    pass # Do something with item

答案 1 :(得分:2)

crawler.start()启动Twisted reactor。只能有一个反应堆。

如果您想运行更多蜘蛛 - 请使用

another_spider = MyAnotherSpider()
crawler.queue.append_spider(another_spider)

答案 2 :(得分:0)

我已经在一个应用程序中使用线程启动了几次reactor并避免了ReactorNotRestartable错误。

主题(目标=的Process.Start)。开始()

以下是详细说明:Run a Scrapy spider in a Celery Task

答案 3 :(得分:-1)

在我看来,您无法使用crawler.start()命令两次:如果您希望它再次运行,则可能需要重新创建它。