2014-10-02 56 views
0

我在Python中編寫了一個spidering腳本,工作得很好。但是,花費很長時間才能完成(9個小時以上,取決於網站的鏈接數量)。什麼是最好的選擇線程在蜘蛛?

我想實現線程,使它花費更少的時間,但我很難找出哪個部分是最好的線程。乍一看,我會創建線程去獲取每個頁面的頁面內容,然後鎖定visited_urlsto_visit_urls陣列,以確保所有內容都可以使用相同的列表。

但似乎它可能花費大多數時間檢查visited_urlsto_visit_urls數組中的重複項,那麼以這種方式進行線程實際上可以節省我多少時間?有沒有更好的方法來纏繞我的蜘蛛?

+1

如果你異形你的代碼,並花費上隸屬檢查多少時間,也許你正在使用'list'爲'visited_urls'和'to_visit_urls'具有爲O(n )查找。嘗試使用'set'代替O(1)查找。 – 2014-10-02 15:24:11

+0

我還沒有分析我的代碼,我只有_feeling_。 :D – Staunch 2014-10-03 14:07:02

回答

0

您應該使用grequests,它是一個異步版本的請求,允許您一次抓取多個Url,顯着提高吞吐量。如果你遍歷你的網址並在子列表上工作,這將是非常有效的。至於重複,只需將您的列表轉換爲集合,然後將它們移除,因爲集合本質上不支持重複。

urls = [...] 
reqs = [grequests.get(x) for x in urls] 
resp = grequests.map(reqs) 

https://github.com/kennethreitz/grequests

+0

我有一種感覺,轉換爲'set'需要O(n^2)來刪除所有重複項,不是嗎?這比我目前用來保證我即將添加的項目不存在的O(n)效率低得多。雖然我不知道,但無法在任何地方找到這些信息...... – Staunch 2014-10-02 19:05:03

+0

「......沒有**已經存在**在列表中**」,這就是我的意思。 – Staunch 2014-10-02 19:12:04

+0

你確定你的瓶頸不是網絡吞吐量嗎?如果您的網絡速度比您的計算速度快,我會很驚訝。此外,爲什麼你使用兩個列表,而不是迭代一個?另外,如果您在啓動時進行了一次轉換,然後對結果進行迭代,我懷疑您會看到顯着的性能下降。 – ragingSloth 2014-10-02 19:37:13