手寫分佈式爬蟲框架

分佈式爬蟲框架 Demo

記錄用Java開發一個簡單的分佈式爬蟲框架,從最開始的十幾行代碼到開發一個支持集羣、分佈式的爬蟲框架。

代碼地址:單機版本 分佈式版本

起因

在訓練智能問答機器人的模型時,缺少模型數據,決定使用爬蟲進行。
當前每天的生活如下:

  • 寫一個爬蟲抓數據
  • 訓練模型
  • 查看訓練結果

弊端

  • 單線程爬蟲太慢了,沒法充分利用計算資源,亟需性能提升。
  • 目標網站經常變更,勢必經常添加、修改爬取網站。需要一個框架(其實已有很多很好地框架,這裏僅爲了學習)。
  • 手動觸發爬蟲和訓練太蠢了,希望自動觸發,夜裏完成

由於“懶”,第一步第二步佔用了90%的時間,決定將其自動化。

目標

  • 每天凌晨2點定時增量抓取數據並保存
  • 每天凌晨3點訓練模型
  • 每天白天到實驗室增加爬蟲數據源,看結果,調整模型

用最簡單的代碼實現一個爬蟲

用十幾行代碼爬取全站新聞 代碼地址


建立爬蟲模型(接口)

用面向對象的思想將爬取數據抽象爲

  • 任務(主要包含目標網站 url)
  • 爬蟲(執行任務(發起HTTP請求),返回目標 url 的數據)
  • 結果處理(將爬蟲返回的數據處理,主要包含解析、保存)

模型完善
上面的基本模型有了,但是還不夠完善,補充一些東西。

  • 爲了充分利用計算資源,爬蟲和結果都使用多線程執行,線程還要複用,這裏爲他們分爲兩個不同的線程池(IO和計算)。
  • 爲了消除任務創建和爬蟲的耦合,在任務和爬蟲間增加一個隊列(因爲在處理頁面結果時,可能再發出新的爬蟲HTTP請求,或者說創建爬蟲任務)。

初步方案如圖:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-6NSFv1Wb-1591437963199)(https://gitee.com/ChinaLym/learn-spider/raw/single-1.0/spider.png)]

模型解讀

  • 由爬蟲啓動器(SpiderStarter)創建爬蟲任務(SpiderTask)加入到任務隊列(SpiderTaskQueue)
  • 爬蟲管理器(SpiderManager)間歇性的從爬蟲任務隊列中嘗試獲取全部任務,並分配給爬蟲(Spider)使用新線程去爬取
  • 爬蟲(Spider)向任務(SpiderTask)中描述的url發起Http請求並反回結果,交給結果處理器接頭人(ResultHanderManager)然後等等爬蟲管理器(SpiderManager)再次分配任務。
  • 爬蟲結果處理器接頭人(ResultHanderManager)收到結果後開啓處理線程,交給對應的結果處理器(Handler)去處理
  • 爬蟲結果處理器(Handler)來處理返回的數據(匹配想要的內容,保存到希望的文件),若希望爬取深一層的url,也可以在處理過程中創建新的爬蟲任務,扔進爬蟲隊列(SpiderTaskQueue)

觸發

  • 項目啓動時
  • 每天凌晨2點

調用啓動器(SpiderStarter)的start方法即可。

代碼實現
單機版本

使用

想新增加一個網站的爬取處理時,只需要新增一個爬蟲類型:

  • 新建 xxxSpiderTask 類來保存 url 和任務類型
  • 新建 xxxHandler 類來處理新的爬取來的數據

集羣,異構

實驗室裏有多臺電腦,想充分利用這些電腦,就得讓自己的爬蟲支持集羣,由於爬蟲本身並不關心是否支持集羣,那就從剛纔搭好的框架做,框架實現,所有爬蟲便全都支持。

需要改動的點

由於我們已經使用面向對象的思想建立好了模型,因此想支持集羣只需要多個實例共享 Task 的狀態即可。故只需要將 SpiderTaskQueue 切換爲消息中間件,並實現Task的序列化即可。

其中消息中間件開源的有如 RabbitMq、KafKa 等,序列化直接用 Json 就好了。

代碼參見 Gitee

分佈式

集羣后其實一個實例既能爬取,又能處理,但爬蟲和處理消耗的資源不對等,因此決定將它拆開,分開運行,同時實驗室有專門的同學也可以用python寫爬蟲,也有會Java的同學專門做數據處理,充分發揮各個語言的優勢。

.#### 需要改動的點

爲了解決這個問題很簡單,我們只需要將爬蟲執行器和處理器分開即可,只需要添加一個爬蟲結果隊列,爬蟲執行完後,將結果放置在隊列中,爬蟲結果處理器從這個隊列裏取就好了。

代碼參見 爬蟲執行器代碼 爬蟲處理器代碼

這樣可以更加合理的利用計算機資源。

  • 當爬蟲任務大量增加時,便可以只部署爬蟲執行實例,快速爬取。
  • 當爬蟲結果多但任務少時,可以減少爬蟲執行器的實例,增加結果處理實例加速解析。

後語

本框架僅爲思想啓發,如何將一個問題更好地解決,未關注性能問題,實現中有很多可以優化的點~。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章