大規模非同步新聞爬蟲的分散式實現

王平發表於2019-06-10

前面我們講了《大規模非同步新聞爬蟲的實現思路》,在文章最後提到了把它升級為分散式的思路。今天,我們就來詳細實現一下,把它真正升級為分散式的大規模非同步爬蟲。

大規模非同步新聞爬蟲的分散式實現

一、架構

我們設計的這個分散式是典型的CS架構,也就是分為伺服器端和客戶端。伺服器端我們稱為“爬蟲Server”,客戶端稱為“爬蟲Client”。

爬蟲Server,負責管理所有URL(即,爬蟲客戶端的下載任務)的狀態,透過我們前面介紹的UrlPool(網址池)進行管理。還不知道UrlPool的同學可以搜尋我們前面的文章,或者到《猿人學網站》上去看“Python爬蟲教程”找到UrlPool的講解。Server提供介面給Clients,以便它們獲取URL和提交URL。

爬蟲Client,負責URL的下載、網頁的解析以及儲存等各種。Client透過介面向Server請求需要被下載的URL,下載完成後向Server報告URL是否下載成功,同時把從網頁中提取到的URLs提交給Server,Server把它們放入URLPool。

Server和Client的分工明確,由它們組成的分散式爬蟲的架構就是這樣子的:

分散式爬蟲設計圖

我們把這個分散式爬蟲叫做“bee”(小蜜蜂),寓意一群蜜蜂去採蜜。分別建立Server和Client的檔案:

bee_server.py

bee_client.py

 

二、爬蟲Server端實現

爬蟲Server端需要建立一個服務,它可以是TCP的,也可以是HTTP的。這裡,我們選擇Python的非同步web框架:Sanic 來寫這個服務。這個服務很簡單,程式碼如下:

用sanic做服務端

上面是web服務的實現程式碼,透過

@app.listener(‘after_server_stop’)

在Server退出前,快取URLPool裡面的url。

整個web服務就實現了一個介面:/task, 透過GET方法讓client獲取URLs,透過POST讓client提交URLs。

後面再加上執行程式:

分散式服務端程式入口

 

三、爬蟲Client的實現

我們把Client寫成一個類,這個類一部分介面是與Server互動用的,也就是從Server那裡獲取要下載的URL,以及向Server提交新得到的URLs。另外一部分介面是與網際網路互動的,即下載URLs。

透過非同步IO,我們可以把Client的併發提高上去,達到更高的抓取速度。

先來看看這個類的初始化:

分散式爬蟲客戶端設計

其中,self._workers 記錄當前正在下載的協程(即,併發數);

sellf.workers_max 是限制最大併發數,根據自己的CPU效能和網路頻寬調整其大小,從而達到最大效率利用硬體資源。

download()方法是對aiohttp的封裝,方便非同步下載。

下面是與Server服務進行互動的兩個方法:

分散式爬蟲服務端和客戶端互動

下面是下載任務相關的方法。其中save_html()根據自己需要可以把下載的網頁儲存到資料庫;filter_good()清洗提取到的URLs,把不需要下載的URLs扔掉。process()是個協程定義,它的工作就是下載、提取、儲存、提交,這個協程會在抓取迴圈中被不斷的建立,達到併發的目的。

服務端處理html的方式

最後,我們定義兩個迴圈,一個用於定時向Server請求要下載的URLs,另一個用於排程下載任務處理協程。透過self._workers這個計數器限制協程數量。start()方法就是整個類的執行入口。

用協程來提高服務端的處理能力

最後的最後,我們需要執行Client:

新聞爬蟲客戶端的入口

 

四、執行和部署

執行過程很簡單,先執行Server程式:bee_server.py

執行分散式爬蟲的服務端

再執行Client程式: bee_client.py

執行分散式爬蟲的客服端

部署的話,可以單機也可以多機。

如果你的伺服器很強,多核的,單機可能就滿足你的下載量的需求了。首先執行一個Server,剩下client的執行數量根據核數來定。單核大約佔50%的CPU,自己多跑跑看。

如果你的下載量很大,比如實時抓取幾千家新聞網站,那麼可以多臺、多核進行部署。這時候,記得改一下Server監聽的host為0.0.0.0,以便其它機器能訪問它。

這就是一個分散式的爬蟲,道理很簡單,實現也不復雜。由於UrlPool的支援,你的Server可以隨時停掉重啟,然後繼續無重複下載。在這套程式碼上面,修改部分介面,就可以實現你自己的抓取目的。

老規矩,猿人學Python公眾號後臺回覆“bee”獲取相關程式碼。

———————————–

廣而告之,最近我在教爬蟲

一對一教學Python爬蟲;

學會如何設計抓取海量資料的爬蟲;

學會如何分析/反反爬策略;

學完自己能真實動手開發那種;

在猿人學Python公眾號選單欄-聯絡我,找到我的微信。

 

爬蟲文章擴充閱讀:

如何讓爬蟲一天抓取100萬張網頁

大規模非同步新聞爬蟲的實現思路

逆向js加密,程式碼混淆不是難事

爬蟲小偏方:robots.txt快速抓取網站的小竅門

爬蟲掙錢系列-(完結篇)結構化人名掙錢第三篇

猿人學banner宣傳圖

我的公眾號:猿人學 Python 上會分享更多心得體會,敬請關注。

***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***

相關文章