在 scrapy 蜘蛛中使用线程

Using threads within a scrapy spider

是否可以在 scrapy 蜘蛛中使用多个线程?例如,假设我构建了一个蜘蛛,它可以抓取博客主题并保存其中的所有消息。我想将每个主题耦合到池中的线程,线程将抓取所有需要的信息。每个线程将以这种方式抓取不同的主题..

Scrapy 本身是单线程的,因此您 不能 在蜘蛛中使用多个线程。但是,您可以同时使用多个蜘蛛 (CONCURRENT_REQUESTS),这可能会对您有所帮助 (see Common Practices)

Scrapy 不使用多线程,因为它建立在 Twisted 之上,这是一个异步 http 框架。

标记的答案并非 100% 正确。

Twisted 上的 Scrapy 运行s,它支持从管道 process_item 方法返回延迟。

这意味着您可以在管道中创建延迟,例如 threads.deferToThread。这将 运行 你的 CPU 绑定代码在反应器线程池中。请注意在适当的地方正确使用 callFromThread。我使用信号量来避免耗尽线程池中的所有线程,但为下面提到的设置设置良好的值也可能有效。

http://twistedmatrix.com/documents/13.2.0/core/howto/threading.html

这是我的项目管道之一的方法:

def process_item(self, item, spider):
    def handle_error(item):
        raise DropItem("error processing %s", item)

    d = self.sem.run(threads.deferToThread, self.do_cpu_intense_work, item)
    d.addCallback(lambda _: item)
    d.addErrback(lambda _: handle_error(item))
    return d

大家不妨关注一下

REACTOR_THREADPOOL_MAXSIZE 如此处所述:http://doc.scrapy.org/en/latest/topics/settings.html#reactor-threadpool-maxsize

CONCURRENT_ITEMS 如此处所述 http://doc.scrapy.org/en/latest/topics/settings.html#concurrent-items

尽管如此,您仍然面临 Python GIL,这意味着 CPU 高强度任务不会真正 运行 在多个 CPU 上并行,它们只会假装那样做。 GIL 仅针对 IO 发布。但是您可以使用此方法在项目管道内使用 IO 阻塞第 3 方库(例如 Web 服务调用),而不会阻塞反应器线程。