【问题标题】:Scrapy crawl multiple times in long running processScrapy在长时间运行的过程中多次爬行
【发布时间】:2016-02-09 10:03:21
【问题描述】:

所以,我创建了这个类,以便我可以使用 Scrapy 按需抓取:

from scrapy import signals
from scrapy.crawler import CrawlerProcess, Crawler
from scrapy.settings import Settings


class NewsCrawler(object):

    def __init__(self, spiders=[]):
        self.spiders = spiders
        self.settings = Settings()

    def crawl(self, start_date, end_date):
        crawled_items = []

        def add_item(item):
            crawled_items.append(item)

        process = CrawlerProcess(self.settings)

        for spider in self.spiders:
            crawler = Crawler(spider, self.settings)
            crawler.signals.connect(add_item, signals.item_scraped)
            process.crawl(crawler, start_date=start_date, end_date=end_date)

        process.start()

        return crawled_items

基本上,我有一个长时间运行的进程,我会多次调用上述类的crawl方法,像这样:

import time


crawler = NewsCrawler(spiders=[Spider1, Spider2])

while True:
    items = crawler.crawl(start_date, end_date)
    # do something with crawled items ...
    time.sleep(3600)

问题是,第二次调用crawl,会出现这个错误:twisted.internet.error.ReactorNotRestartable

据我所知,这是因为反应堆停止后无法运行。有什么解决办法吗?

谢谢!

【问题讨论】:

    标签: python scrapy web-crawler reactor


    【解决方案1】:

    这是目前scrapy(twisted)的一个限制,并且很难将scrapy用作库。

    您可以做的是派生一个新进程,该进程运行爬虫并在爬虫完成时停止反应器。然后,您可以等待加入并在爬网完成后生成一个新进程。如果要处理主线程中的项目,可以将结果发布到队列。不过,我建议您为您的项目使用自定义管道。

    看看我下面的回答:https://stackoverflow.com/a/22202877/2208253

    您应该能够应用相同的原则。但你宁愿使用多处理而不是台球。

    【讨论】:

    • 谢谢!然而,使用Queue 真的很慢,我最终使用pickle 将爬取结果传达给主线程,直到我找到另一个替代方案。你有什么建议吗?
    • 我会创建一个定制的管道来处理抓取的项目。然后,您可以选择适合您需要的数据结构,然后在爬网完成后让您的后处理器处理这些项目。您需要等待抓取完成吗?如果没有,我只会在管道中动态处理这些项目。
    • 所以队列很慢,因为我用错了。我在加入流程后使用了它。当我 queue.get() 加入该过程之前,它运行良好。不过,我不知道为什么我必须在加入流程之前这样做?
    【解决方案2】:

    基于上面@bj-blazkowicz 的回答。我找到了一个使用 CrawlerRunner 的解决方案,这是在运行多个蜘蛛时推荐使用的爬虫,如文档https://docs.scrapy.org/en/latest/topics/practices.html#run-scrapy-from-a-script

    中所述

    还有另一个 Scrapy 实用程序可以更好地控制爬取过程:scrapy.crawler.CrawlerRunner。这个类是一个瘦包装器,它封装了一些简单的帮助器来运行多个爬虫,但它不会以任何方式启动或干扰现有的反应器。

    使用这个类,应该在调度蜘蛛之后显式运行反应器。如果您的应用程序已经在使用 Twisted 并且您想在同一个反应器中运行 Scrapy,建议您使用 CrawlerRunner 而不是 CrawlerProcess。

    这是我的解决方案:https://stackoverflow.com/a/71643356/18604520

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-04
      • 2021-01-13
      • 2016-03-30
      • 1970-01-01
      相关资源
      最近更新 更多