2016-11-30 41 views
0

我用Python做了簡單的網絡爬蟲。到目前爲止,它所做的一切都會創建一組應該訪問的網址,這是一組已經訪問過的網址。在解析頁面時,它會將該頁面上的所有鏈接添加到應該訪問的集合中,並將頁面url添加到已訪問的集合中,等等,而should_be_visited的長度大於0.到目前爲止,它在一個線程中執行所有操作。針對網絡爬蟲的Python線程或多處理?

現在我想爲此應用程序添加並行性,所以我需要具有相同類型的鏈接和很少的線程/進程,其中每個將從should_be_visited中彈出一個url並更新already_visited。我真的迷失在線程和多處理,我應該使用,我需要一些池,隊列嗎?

+0

對於要訪問的URL集合,它們中的很多是同一臺服務器還是全部來自不同的服務器? – halfer

+0

所有的都是一樣的 – wasd

+1

好的,在這種情況下,你可能根本不應該平行,除非服務器在你的控制之下,並且你的服務器/網絡能夠處理負載。對於遠程管理員認爲拒絕服務攻擊的請求,您應該在每個請求之間稍稍延遲一段時間,而不是加快請求速度,可能會延遲一兩秒。廣泛的抓取規則是**它應該慢慢完成,而不是快速**,並且未能觀察到這可能會將您的服務器放在IP阻止列表中。 – halfer

回答

1

當決定是否在Python中使用線程時的經驗法則是詢問線程將執行的任務是CPU密集型還是I/O密集型問題。如果答案是I/O密集型的,那麼你可以使用線程。

由於GIL,Python解釋器一次只能運行一個線程。如果某個線程正在執行一些I/O操作,它將阻止等待數據變爲可用(例如,從網絡連接或磁盤),同時解釋器將上下文切換到另一個線程。另一方面,如果線程正在執行CPU密集型任務,其他線程將不得不等待解釋器決定運行它們。

Web爬網主要是一個I/O導向的任務,您需要建立HTTP連接,發送請求,等待響應。是的,在得到響應之後,您需要花費一些CPU來解析它,但除此之外,它主要是I/O工作。所以,我相信,在這種情況下,線程是一個合適的選擇。

(當然,尊重robots.txt的,和不困請求過多而服務器:-)

0

另一種方法是異步I/O,這是很多這類的我更好/ O-bound任務(除非處理頁面是真的昂貴)。您可以使用asyncioTornado來嘗試使用它的httpclient