天天看點

記第一次讀源代碼 -- WebMagicSummary

Summary

閱讀了好久

webmagic-core

源碼,總想寫點什麼。。。故在今終結之日(18/01/08),寫個小結。

其實,此時又是新的開始~

從何寫起?

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

記第一次讀源代碼 -- WebMagicSummary

那就先來總結一下我的閱讀過程吧!這是我第一次閱讀大型架構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

    完成的。然後,貼一張類圖就可以說清楚了。
    記第一次讀源代碼 -- WebMagicSummary
    雖然簡單但是在這裡我也有個發現。我通過結合

    spider

    downloader

    發現,初始化的線程數(也就是設定的并行爬蟲數)與後面設定的連接配接池大小相同。這樣設計是合理,一個爬蟲正好可以得到一個連接配接。
  • selector

    盡顯(作者)英雄本色

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

    記第一次讀源代碼 -- WebMagicSummary
    沒錯,就是如此龐大,完全展示了作者的綜合實力。其實,此部分的類結構并不是很複雜,但是涉及面比較廣。這部分作者使用了

    fastJson

    jsonPath

    jsoup

    regex

    基于行塊分布函數的通用網頁正文抽取算法

    ,而且作者巧妙的把它們組合在一起,實作了

    鍊式API

    。很佩服作者!
  • pipeline

    &

    processor

    略施小計

    pipeline

    定義了輸出接口,并給出了幾種實作。話不多說很簡單。而

    processor

    隻是定義了處理頁面(包含

    fetch url

    &

    save result

    ),需要使用者根據自己的爬取需求自定義,就更簡單了。

    戰事已盡,已近歸期。

3. 蓦然回首

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

記第一次讀源代碼 -- WebMagicSummary

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

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

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