標籤:網路爬蟲 python 線程池
一,我是如何使用Python抓取網頁的
我知道Python有一個爬蟲架構scrapy,但是目前還沒有學習,並且也沒有什麼很棘手的的問題需要去使用一個爬蟲架構,所以我就用Python內建的urllib,將目標網頁爬下來,然後用正則過濾出自己需要的內容。
二,效率問題
上面的方法簡單,真的是上手即用,但是問題是效率問題,如果一個網頁一個網頁的抓,顯然頻寬無法達到最高,浪費了大部分頻寬,這時候大部分人都會想到,多線程啊!
對,但是我們大部分人又都會寫出下面的代碼
# 總任務數有500個while i < 500: thirdList = [] # 每次開50個進程跑,這50個完了再開下一次50個線程 for x in range(50): t = threading.Thread(target = loop) t.start() thirdList.append(t) for t in thirdList: t.join()
這樣做確實效率會提升一大截,因為畢竟是多線程了嘛,以前一個一個,現在50個50個的,肯定會提高效率,這種方式具體的網路佔用情況見下面:
我們注意到,網路佔用是一段一段的,突然變高又突然降低,這很容易理解,開始50個一起工作,肯定網路佔用大,然後任務一個一個都完成了,網路佔用肯定就又低了,等下一次50個來了,網路佔用又變高了。
這就是我們想要的嗎?肯定不是,我們需要的是一個能穩定佔用寬頻資源的程式,所以就有了線程池的應用。
三,簡易“線程池”
思想是這樣的,我們需要有一個機制,可以限制線程的個數,一個線程工作完成了,新的線程進來,並且如果某個線程工作逾時,就自動結束(抓取大量網頁,少一些是可以允許的)。
要解決的問題又兩個:
(1)如何限制線程個數
(2)如何?逾時自動結束
(1)如何限制線程個數
我的辦法很簡單,就是計數,全域變數用來記錄已經啟動的線程的個數,然後,這個線程退出之前必須將線程數減一,這樣,就可以控制線程個數
(2)如何?逾時退出
這個問題在我這個爬蟲上很簡單,逾時就是網路連接逾時,這個時間是可以設定的,就是下面這一句:
# 設定逾時時間socket.setdefaulttimeout(10)
線上程中try-except檢測:
try: request = urllib.urlopen(pageUrl)# 任何異常都退出,包括了逾時異常except Exception, e: # 減少一個線程 thirdCount -= 1 return
就是這樣,很容易一個“線程池”實現了,下面是使用這種方法的效果:
抓取過程中,網路都是被100%利用了的。
代碼在這
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
簡易“線程池”在Python網路爬蟲中的應用