1. 程式人生 > >記第一次讀原始碼 -- WebMagic

記第一次讀原始碼 -- WebMagic

Summary

閱讀了好久 webmagic-core 原始碼,總想寫點什麼。。。故在今終結之日(18/01/08),寫個小結。
其實,此時又是新的開始~

從何寫起?

一開始先介紹一下它的總體框架?我不想這麼來,因為作者已經介紹了很清楚。所以,這裡直接拿作者的一幅圖來概述(更詳細的資訊可以去參考它的Github主頁)。

image

那就先來總結一下我的閱讀過程吧!這是我第一次閱讀大型框架or系統原始碼,所以可能走了一些彎路。寫於此,希望可以總結經驗不斷成長。

我大概是按照如下順序來閱讀的:
1. 始於 Spider.java奠定根基
2. 逐個擊破各個模組,群雄逐鹿,一統天下


1. downloader
2. scheduler
3. selector
4. pipeline & processor
3. 歸於 Spider.java驀然回首

以上就是大概流程,下面開始稍微詳細地回顧。

1. 奠定根基

  • 為何選擇要起於 Spider.java

    前期,我使用 WebMagic 做過關於 知乎 的爬取。所以我大概知道了它的流程。之所以從它開始,因為 ++它是整個框架的入口++ 。

  • 這一階段詳細看了哪些,又遮蔽了哪些內容?

    在這個階段我先是自己寫了一個小的爬取案例,然後根據此案例順藤摸瓜依次來分析 spider 以及與它相關的內容。現在感到這種方法雖然可以快速地入手,但是未免有點以偏概全的感覺(個人理解)。但是,這樣做應該是正確的。

    於是,我先從它的 run() 方法開始,然後遇到了各種初始化,緊接著出現了處理過程,最後的出現很明顯就是回收了。我記得在這個過程中我幾乎每遇到一個方法(除那些該階段要遮蔽的外)就詳細閱讀。若大概明白了就在方法上標註 OK ,若有歧義就會弄個 TODO 。現想起來這樣做消耗了大量時間,可是當時並不知道其他的方法。。。

    至於此階段著重的內容,我把 初始化 各個模組間的通訊實體 部分回收 當作重點,而遮蔽了 各個模組間的具體實現 。說白了,就是看清它們的 input output。儘管這樣,我還是遇到了很多的挑戰。比如,未知實現過程就先去了解它們的通訊,這往往需要大膽的猜測!!!

  • 這一階段地收穫有哪些?

    對我來使,這一階段的最大收穫就是找到了一個 BUG 。對沒錯就是一個 bug ,在我發現且經過反覆的驗證後,在第一個時間通過 issues 提交給了原作者。估計作者太忙了沒有給回覆,但是有幾個網友確認了。我還是很激動的,儘管我給出的修復也被指出了問題( ̄□ ̄||)。

    至於,其他的收穫大部分都是關於多執行緒的。但有種 似有若為 的感覺,希望就像”胖子”所說的那樣:++這些都是潛移默化的!++

2. 群雄逐鹿

  • 聽說你在與 downloader 爭霸時差點 喪命

    你聽誰說的(-_-||)!

    Downloader 是我進擊的第一個模組,想必大家都能看出它的功能:下載指定頁面。下載就要涉及網路、連線了。那麼它是怎麼實現的呢?通過 先鋒官 的幾次試探,不難發現它是借用的 httpClient 。既然這樣,我便著手 httpClent 。因為知彼知己,方能百戰不殆。但,接下來的事萬萬沒想到~

    其實,一開始我想了好幾種方案用於研究 HttpClient。但,最後我可能選擇了最“浪”的一種(驕傲啦?),直接上官方文件讓我來一探究竟。誰知,它是一本 天書 (鳥語性),慢慢品味吧。我愣是硬著頭皮讀了 20 多頁,它介紹的是真的真的詳細,部分內容我竟然完全看不懂。感覺自己的網路學的更 shit 一樣。++幸好,大學還沒結束,一定要補上!++ 唉,這不懂,那也不懂,放棄吧!很是糾結(ー`´ー)。。。

    想當初,一統天下的雄心哪去了?我不會把第一次讀原始碼弄 流產 吧?不!對啊,我可以標 TODO 。於是,我忽略了 證書 SSL SOCKET & Connection pool,它們無傷大雅~~ 最終終於熬過來了。

    現在看來,這裡收穫頗多。比如,部分理解了 套接字程式設計 ,還發現了自己在網路方面的漏洞!

  • scheduler so-easy ?

    確實,scheduler 模組很簡單,它主要依賴 blockingQueue 完成的。然後,貼一張類圖就可以說清楚了。

    image

    雖然簡單但是在這裡我也有個發現。我通過結合 spiderdownloader 發現,初始化的執行緒數(也就是設定的並行爬蟲數)與後面設定的連線池大小相同。這樣設計是合理,一個爬蟲正好可以得到一個連線。

  • selector 盡顯(作者)英雄本色

    先貼上此部分的類圖壓壓驚。

    image

    沒錯,就是如此龐大,完全展示了作者的綜合實力。其實,此部分的類結構並不是很複雜,但是涉及面比較廣。這部分作者使用了 fastJson jsonPath jsoup regex 基於行塊分佈函式的通用網頁正文抽取演算法,而且作者巧妙的把它們組合在一起,實現了 鏈式API。很佩服作者!

  • pipeline & processor 略施小計

    pipeline 定義了輸出介面,並給出了幾種實現。話不多說很簡單。而 processor 只是定義了處理頁面(包含 fetch url & save result),需要使用者根據自己的爬取需求自定義,就更簡單了。

    戰事已盡,已近歸期。

3. 驀然回首

看一看我的最終佈局(其實是在第一階段畫的,可能有點亂,後期太忙沒畫~)

image

回顧整個過程,大約有兩三週,當然其中有很多時間忙於其他事務。現在一看,說簡單也簡單,現在可以大概的說明每個地方的功能;說複雜當然也很複雜,自己是不可能設計出來的!

第一次走的路,也不知道有哪些是彎路,期待下次起航!

最後,任重而道遠! 還有就是胖子常說的 路漫漫其修遠兮,吾將上下而求索