2015-04-06 51 views
3

scrapy蜘蛛中可以使用多個線程嗎?例如,假設我已經構建了一個抓取博客主題並保存所有消息的蜘蛛。我想將每個主題都連接到池中的一個線程,並且該線程將抓取所有需要的信息。每個線程會爬的不同話題的方式..在scrapy spider中使用線程

回答

6

Scrapy本身是單線程的,並且最終你不能使用蜘蛛內的多個線程。但是,可以利用多個蜘蛛在同一時間(CONCURRENT_REQUESTS),它可以幫助你(see Common Practices

,因爲它是建立在Twisted,這是一個異步HTTP框架Scrapy不使用多線程。

+0

如果我在spider代碼中創建一個python線程池,爲什麼它不能支持這些線程? – Eran

+2

@Eran因爲蜘蛛代碼的底層框架是異步的, – miradulo

6

標記的答案不是100%正確的。

Scrapy在Twisted上運行,它支持從管道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阻塞第三方庫(例如webservice調用),而不會阻塞反應器線程。