1. 程式人生 > >爬網易雲音樂評論數的優化歷程

爬網易雲音樂評論數的優化歷程

為什麼要爬、怎麼爬就不說了。

首先

我是第一次寫爬蟲。

使用的是Python,且沒有使用爬蟲框架。
僅僅靠requests和beautifulsoup來完成。

作者:軌跡。

方法一:最早使用的方法

爬取過程:
1、模擬請求
2、獲取資料
3、入庫

重複1-3來完成對一首音樂的評論數的爬取。

過程如圖:
pc1
該方法的不足之出在於:
每一次的網路IO都要等待本地IO,每一次的本地IO都要等待網路IO

實際操作時間:
爬100首:
pc1-100

爬500首:
pc1-500

爬5000首:
pc1-5000

我動了動小腦袋瓜,發現事情並沒有這麼簡單:
平均一首需要:0.9秒
那麼爬1,000,000就需要:900,000秒=250小時

=10.4天
就算是個睿智都知道這劃!不!來!

而且,當請求數不斷得增加,即使本地IO保持穩定,但網路IO不好說呀。而且測試時間恰逢下午至晚上,這可能是網易雲音樂伺服器的高峰期,網路IO情況就更不容樂觀了。

根據該方法的不足之處,我又寫了一個方法二。

方法二:方法一的改進,讓請求的只做請求,入庫的只做入庫。

既然方法一的網路IO和本地IO需要互相等待。

不如讓網路IO跑在一個執行緒,本地IO跑在一個執行緒如何?
用FIFO佇列作緩衝?

過程如圖:
這裡寫圖片描述

爬100首:
pc2-100
爬500首:
pc2-500
爬5000首:
pc2-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的執行緒呢??

過程:
pc3

等等,這不是生產者消費者問題嗎!!

要不要加寫鎖?要不要加讀鎖?
額不不不,還好Python的Queue自帶鎖,是執行緒安全的!
那就放開寫吧。

2執行緒各爬100:
pc3-2-100
3執行緒各爬100:
pc3-3-100
4執行緒各爬100:
pc3-4-100


8執行緒各爬100:
這裡寫圖片描述
16執行緒各爬100:
pc3-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天。真讓人頭疼。。。