記第一次讀原始碼 -- WebMagic
Summary
閱讀了好久
webmagic-core
原始碼,總想寫點什麼。。。故在今終結之日(18/01/08),寫個小結。
其實,此時又是新的開始~
從何寫起?
一開始先介紹一下它的總體框架?我不想這麼來,因為作者已經介紹了很清楚。所以,這裡直接拿作者的一幅圖來概述(更詳細的資訊可以去參考它的Github主頁)。
那就先來總結一下我的閱讀過程吧!這是我第一次閱讀大型框架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
完成的。然後,貼一張類圖就可以說清楚了。雖然簡單但是在這裡我也有個發現。我通過結合
spider
和downloader
發現,初始化的執行緒數(也就是設定的並行爬蟲數)與後面設定的連線池大小相同。這樣設計是合理,一個爬蟲正好可以得到一個連線。selector
盡顯(作者)英雄本色先貼上此部分的類圖壓壓驚。
沒錯,就是如此龐大,完全展示了作者的綜合實力。其實,此部分的類結構並不是很複雜,但是涉及面比較廣。這部分作者使用了
fastJson
jsonPath
jsoup
regex
基於行塊分佈函式的通用網頁正文抽取演算法
,而且作者巧妙的把它們組合在一起,實現了鏈式API
。很佩服作者!pipeline
&processor
略施小計pipeline
定義了輸出介面,並給出了幾種實現。話不多說很簡單。而processor
只是定義了處理頁面(包含fetch url
&save result
),需要使用者根據自己的爬取需求自定義,就更簡單了。戰事已盡,已近歸期。
3. 驀然回首
看一看我的最終佈局(其實是在第一階段畫的,可能有點亂,後期太忙沒畫~)
回顧整個過程,大約有兩三週,當然其中有很多時間忙於其他事務。現在一看,說簡單也簡單,現在可以大概的說明每個地方的功能;說複雜當然也很複雜,自己是不可能設計出來的!
第一次走的路,也不知道有哪些是彎路,期待下次起航!
最後,任重而道遠! 還有就是胖子常說的 路漫漫其修遠兮,吾將上下而求索。