爬網易雲音樂評論數的優化歷程
為什麼要爬、怎麼爬就不說了。
首先
我是第一次寫爬蟲。
使用的是Python,且沒有使用爬蟲框架。
僅僅靠requests和beautifulsoup來完成。
作者:軌跡。
方法一:最早使用的方法
爬取過程:
1、模擬請求
2、獲取資料
3、入庫
重複1-3來完成對一首音樂的評論數的爬取。
過程如圖:
該方法的不足之出在於:
每一次的網路IO都要等待本地IO,每一次的本地IO都要等待網路IO
實際操作時間:
爬100首:
爬500首:
爬5000首:
我動了動小腦袋瓜,發現事情並沒有這麼簡單:
平均一首需要:0.9秒
那麼爬1,000,000就需要:900,000秒=250小時
就算是個睿智都知道這劃!不!來!
而且,當請求數不斷得增加,即使本地IO保持穩定,但網路IO不好說呀。而且測試時間恰逢下午至晚上,這可能是網易雲音樂伺服器的高峰期,網路IO情況就更不容樂觀了。
根據該方法的不足之處,我又寫了一個方法二。
方法二:方法一的改進,讓請求的只做請求,入庫的只做入庫。
既然方法一的網路IO和本地IO需要互相等待。
不如讓網路IO跑在一個執行緒,本地IO跑在一個執行緒如何?
用FIFO佇列作緩衝?
過程如圖:
爬100首:
爬500首:
爬5000首:
很顯然,時間消耗量下降了不是一點半點。
方法 | 一 | 二 |
---|---|---|
100首 | 61.93 s | 38.41 s |
500首 | 445.23 s | 418.30 s |
5000首 | 4502.55 s | 4974.57 s |
方法三:多執行緒請求
在多執行緒上吃了點甜頭之後,發現本地IO的消耗時間總是比網路IO的消耗時間多那麼零點幾秒。也就說,本地IO總是在等待網路IO請求到的資料。
為什麼不多開幾個網路IO的執行緒呢??
過程:
等等,這不是生產者消費者問題嗎!!
要不要加寫鎖?要不要加讀鎖?
額不不不,還好Python的Queue自帶鎖,是執行緒安全的!
那就放開寫吧。
2執行緒各爬100:
3執行緒各爬100:
4執行緒各爬100:
8執行緒各爬100:
16執行緒各爬100:
執行緒數 | 2 | 3 | 4 | 8 | 16 |
---|---|---|---|---|---|
每個執行緒各100首 | 57.04s | 63.57s | 71.68s | 120.43s | 239.05s |
平均每首 | 0.285s | 0.2119s | 0.1792s | 0.1505s | 0.1494s |
很顯然:
當網路IO的執行緒超過8後,提升非常小,可能是因為各網路IO執行緒在等待其他網路IO執行緒的寫入。
最後
以0.15秒每首的速度爬一百萬首,也需要1.73天。真讓人頭疼。。。