天天看點

WebMagic 剖析

WebMagic 

首先,爬蟲的本質:基于Http協定請求目标位址擷取響應結果解析并存儲。

01

導語

1、爬蟲基礎知識

2、優秀國産開源爬蟲架構webmagic剖析

02

爬蟲基礎

1、爬蟲的本質

爬蟲的本質:基于Http協定請求目标位址擷取響應結果解析并存儲。

2、HTTP請求

  1. 請求頭(Request Headers):包裝了http請求的基本資訊,比較重要的如:user-agent、referer、cookie、accept-language(接受語言)、請求方法(post、get)。
  2. 響應頭(Response Headers):包裝了伺服器傳回的頭資訊,如content-language内容語言、content-type内容的類型text/html等 、server伺服器類型(tomcat、jetty、nginx等)、status響應狀态(如:200、302、404等等)。
  3. Response:服務端具體的傳回,類型多種多樣,有html頁面、js代碼、json串、css樣式、流等等。

3、解析

通常情況下,web傳回的基本都是html頁面、json。

  1. xpath:xml路徑語言,具備很強的解析能力,chrome、firefox都有對應的工具生成xpath文法,可以很友善的對标準html檔案進行解析。
  2. jsonpath:jsonpath是一個json解析的利器,非常類似于xpath文法,用非常簡潔的表達式解析json串。
  3. css選擇器:這裡的css選擇器和jquery有點類似,通過元素的css樣式來定位元素,大名鼎鼎的jsoup提供豐富的css選擇器
  4. 正規表達式
  5. 字元串分割

4、難點

  • 分析請求

ajax的普及,很多網站都采用了動态渲染的模式,請求不再是簡單的傳回html的模式,那麼給爬取帶來了巨大的難度,一般隻能靠分析異步請求傳回的json來具體分析,解析成我們需要的資料格式。還有一類是通過服務端内部轉發來渲染頁面,這類是最難的,請求不是通過浏覽器來請求,而是再服務端跳轉幾次才渲染給浏覽器,這時候需要使用模拟器來模拟請求,如selenium等。

  • 網站的限制
    • cookie限制:很多網站是要登陸後才能繞過filter才能通路,這時候必須模拟cookie
    • user-agent:有的網站為了防爬蟲,必須要求是真正浏覽器才能通路,這時候可以模拟 user-agent
    • 請求加密:網站的請求如果加密過,那就看不清請求的本來面目,這時候隻能靠猜測,通常加密會采用簡單的編碼,如:base64、urlEncode等,如果過于複雜,隻能窮盡的去嘗試
    • IP限制:有些網站,會對爬蟲ip進行限制,這時候要麼換ip,要麼僞裝ip
    • 曲線方案:對應pc端,很多網站做的防護比較全面,有時候可以改一下思路,請求app端服務試試,通常會有意想不到的收獲。
  • 爬取深度

網站通常的表現形式是一個頁面超連結着另外的頁面,理論上是無限延伸下去的,這時候必須設定一個爬取深度,不能無窮無盡的爬取。

  • 總結

爬蟲本質上隻做了兩件事情:請求和解析結果,但是爬蟲的開發是非常困難的,需要不停的分析網站的請求,不停的跟随目标網站來更新自己的程式,試探解密、破解目标網站限制,把它當做網絡攻防一點也不為過。

03

webmagic 架構解析

webmagic 是一個優秀的國産爬蟲架構、簡單易用、提供多種選擇器,如css選擇器、xpath、正則等等,預留了多個擴充接口,如Pipeline、Scheduler、Downloader等。

WebMagic 剖析

上圖複制于webmagic官方文檔,webmagic由四部分組成

  • Downloader:負責請求url擷取通路的資料(html頁面、json等)。
  • PageProcessor:解析Downloader擷取的資料。
  • Pipeline:PageProcessor解析出的資料由Pipeline來進行儲存或者說叫持久化。
  • Scheduler:排程器通常負責url去重,或者儲存url隊列,PageProcessor解析出的url可以加入Scheduler隊列,用于下一次的爬取。

Webmagic使用非常簡單,實作PageProcessor 接口,即可利用Spider類啟動爬蟲任務了。

WebMagic 剖析

下面重點解析一下Spider類的幾個重要方法,包括鎖的使用

1、addUrl

WebMagic 剖析

scheduler.push(request, this),把需要爬取的url加入到Scheduler隊列。

2、initComponent

WebMagic 剖析

初始化downloader、pipelines、threadPool線程池,這裡有必要說明一下,webmagic預設down是HttpClientDownloader、預設pipeline是ConsolePipeline.

2、run

run方法是整個爬行運作的核心

WebMagic 剖析
WebMagic 剖析
  • 任務結束時機

隊列為空并且所有正在運作請求完成,且設定了exitWhenComplete為true,這時才會退出任務,這時候必須注意一點是,當頁面請求過于慢,導緻新解析的url來不及進隊列,這時候任務退出導緻爬取不完整。一般設定exitWhenComplete為false,但是有時候開啟兩個爬蟲,必須等上一個爬蟲完成,才運作下一個爬蟲,這時候就會出問題了。實作這種場景,得改一下webmagic源碼

  • 等待新請求時間,預設是30s
  • WebMagic 剖析
    标題
  • 若scheduler隊列裡有url,在把任務丢進線程池,頁面download成功,則執行pageProcessor的process方法,如果有pipeline,則執行pipeline鍊裡的process方法
  • WebMagic 剖析

有一點要注意,對于PageProcessor接口和Pipeline接口的實作,特别要注意線程安全的問題,切記不可對單例集合對象塞元素。

  • 線程池CountableThreadPool的execute方法
WebMagic 剖析
WebMagic 剖析

這裡有死鎖的風險,當threadAlive數大于等于threadNum線程數,reentrantLock.lock()申請鎖,循環condition.await(),與此同時 executorService.execute方法中的threadAlive的decrementAndGet也必須reentrantLock.lock()申請鎖,此時,兩方互相等待資源而造成死鎖,這個小bug調整一下,無礙大局。到時候官方提一個issues

總體說來,Webmagic架構清晰,擴充容易,使用友善,是一款不錯的爬蟲架構。