在scrapy蜘蛛中使用线程

Era*_*ran 3 python scrapy

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

Gre*_*orn 7

标记的答案不是100%正确.

Scrapy在twisted上运行,它支持从管道process_item方法返回延迟.

这意味着您可以在管道中创建延迟,例如from threads.deferToThread.这将在reactor线程池中运行您的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
Run Code Online (Sandbox Code Playgroud)

你可能想要留意

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阻止第三方库(例如webservice调用),而不会阻塞反应器线程.

  • 仍然是一个很好的答案!谢谢。 (2认同)

mir*_*ulo 6

Scrapy本身是单线程的,结果你不能在蜘蛛中使用多个线程.但是,您可以同时使用多个蜘蛛(CONCURRENT_REQUESTS),这可能会对您有所帮助(参见通用实践)

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

  • @Eran因为蜘蛛代码的底层框架是异步的, (2认同)