爬蟲中多線程的運用


檢索百張的頁面,爬蟲運行下來往往在一小時以內,時間上還是可以接受的。但當整理后的URL數量過多的時候,就只能考慮采取多線程分步爬取了。Python里控制多線程只需要用到模板threading,而且只需要用到其中的Thread。

簡單的使用方法如下:

 1 import time
 2 import threading
 3 
 4 def spider(number):
 5     print u"%d 號爬蟲開始運行! 時間: %s" % (number,time.strftime('%H:%M:%S',time.localtime()))
 6     time.sleep(2)
 7     print u"%d 號爬蟲運行結束! 時間: %s" % (number,time.strftime('%H:%M:%S',time.localtime()))
 8     
 9 if __name__ == "__main__":
10     thread = 5
11     print u"主程序開始運行! 時間: %s" % time.strftime('%H:%M:%S',time.localtime())
12     for i in range(1,thread+1):
13         t = threading.Thread(target=spider,args=(i,))
14         t.start()
15     
16     print u"主程序運行結束! 時間: %s" % time.strftime('%H:%M:%S',time.localtime())
Thread使用方法為:
threading.Thread(target=線程運行的函數,args=(參數)) 其中參數用逗號分隔,並以逗號結尾。
隨后使用start啟動。
運行結果如下:

可以看到五個線程同步運行,因sleep設置的時間相同,所以也同步結束。

但有一個缺點是第16行代碼在五個線程啟動后隨即也就運行了,相當於此時主線程已經結束了而那五個子線程還在運行。

控制策略有兩個

在start之前把子線程設置為守護線程

修改代碼如下:

1 for i in range(1,thread+1):
2   t = threading.Thread(target=spider,args=(i,))
3   t.setDaemon(True)
4   t.start()

運行結果如下:

子線程在主線程結束的時候也同步結束,未運行的部分也就不再運行了。

在主線程中使用join,讓主線程掛起等待子線程結束

修改代碼如下:

1 for i in range(1,thread+1):
2     t = threading.Thread(target=spider,args=(i,))
3     t.start()
4 t.join()

從運行結果可以看到主線程停留在t.join()的位置,一直等到五個子線程全部結束后才開始繼續向后運行。

以上就是需要用到的threading模板里所有的東西了。

在整理好需要處理的數據列表后,我們只需要將列表分段分別交給不同的線程來處理,主線程等待所有數據處理完畢之后再進行下一步操作,如下:

 1 import time
 2 import threading
 3 
 4 def spider(number,data_list):
 5     print u"%d 號爬蟲開始運行! 時間: %s" % (number,time.strftime('%H:%M:%S',time.localtime()))
 6     print u"%d 號爬蟲需要處理的數據有%s ! 時間: %s" % (number,str(data_list),time.strftime('%H:%M:%S',time.localtime()))
 7     time.sleep(2)
 8     print u"%d 號爬蟲運行結束! 時間: %s" % (number,time.strftime('%H:%M:%S',time.localtime()))
 9     
10 if __name__ == "__main__":
11     thread = 5
12     ls = []
13     ls2 = []
14     for n in range(1,58):
15         ls.append(n)
16     length = len(ls)//thread+1
17     for m in range(thread):
18         ls2.append(ls[length*m:length*m+length])
19         
20     print u"主程序開始運行! 時間: %s" % time.strftime('%H:%M:%S',time.localtime())
21     for i in range(1,thread+1):
22         t = threading.Thread(target=spider,args=(i,ls2[i-1],))
23         t.start()
24     t.join()
25     print u"主程序運行結束! 時間: %s" % time.strftime('%H:%M:%S',time.localtime())

運行結果如下:

五個線程分步處理各自被分配到的數據,總體運行時間大幅縮減。當然機器給力的話,可以增加線程數,得到更快的速度。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM