使用 webMagic 註解爬取網頁數據

不久前使用 webMagic開發了一款爬蟲

爬取對象爲四川政務網,使用JFinal持久化數據

如果你正在學習爬蟲,或者業務與我類似,那麼你可以下載源碼學習

也可向我提出改進意見

參考源碼:在這裏

列表頁:

http://www.sczwfw.gov.cn/app/index?flag=2&areaCode=510000000000

抓取頁:

http://www.sczwfw.gov.cn/app/scworkguide/detail?id=3952148991995600896&shardKey=5100

 

簡單講下系統設計,具體的請參考代碼

目錄結構

entity 網頁字段對應的實體類 

main 爬蟲入口

utils 工具類 

Admin : 對所有提取到的數據進行集中管理

UrlCache: 網頁緩存的抽象

 

生命週期

如圖所示,保存數據只是附屬的流程

 

鏈接發現

這是爬蟲的開始,對鏈接進行發現和更新

例如:已經抓取了500個成都的事項,但是現在需要更新500個事項爲其他地區的

按照生命週期,你需要在這裏重新更新鏈接

 

在這一步,我們需要確認要抓取的網頁是哪些,並觀察網頁是否有對外暴露的查詢接口,經過調試,找到了這個接口:

http://mss.sczwfw.gov.cn/app/powerDutyList/getThImplement

他支持的參數:

eventNam: 事項名稱

areaCode : 區域碼

eventType : 行政類型 

打開PostMan測試接口,並查看返回參數:

它返回了事項的基本信息,其中還有父級事項的名稱

循環調用這個接口,然後將其返回的數據進行保存,具體請參考utils包下的InsertItems類,看我如何抽離數據

將其保存至數據庫

 

OOSpider

當數據準備就緒,需要使用OOSpider類進行網頁數據抓取

OOSpider是註解式爬蟲的入口,有這些方法

方法


getCollectorPipeline() : 看了下源碼,這個和AfterExtractor接口的功能一樣,都是在運行時返回數據抽取結果。建議使用AfterExtractor接口,面向接口編程嘛

 兩個create方法: 對構造方法的簡單封裝,因爲構造方法是protected!

addPageModel(): 文檔

setIsExtractLinks(): 是否提取網頁鏈接
這個需要搭配TargetUrl與HelpUrl註解使用,本質就是鏈接發現.我們已經發現過了,所以設置爲false
具體的你可以看ModelPageProcessor源碼

TargetUrl和HelpUrl註解文檔

入參

ModelPageProcessor : 註解網頁對象  在網頁抓取章節裏詳解介紹

PageProcessor: 普通網頁對象  這個是給傳統方式使用的,看 這裏

Site : http請求對象 , http嘛肯定是配置cookies、header、超時時間、重試次數等等...亂七八糟參數的地方

PageModelPipeline : 看 文檔 

 

網頁抓取

下面我分成兩個部分講述

1. 創建OOSpider時 發生了什麼

2.如何設計映射關係(實體類)

 

先看一段代碼:

public class GithubRepo {
    @ExtractBy("//div[@id='readme']/tidyText()")
    private String readme;

    public static void main(String[] args) {
        OOSpider.create(Site.me().setSleepTime(1000)
                , GithubRepo.class)
                .addUrl("https://github.com/code4craft").thread(5).run();
    }
}

這段代碼描述了:

1 . GithubRepo 擁有的字段readme 被@ExtractBy 註釋,它的抽取規則爲//div[@id='readme']/tidyText()

2.創建一個爬蟲  OOSpider.create()

3. 爬蟲傳入了兩個類 : Site類 和 擁有抽取規則的類

4.使用addUrl(),規定了抓取的頁面

5.創建線程並運行

 

代碼內部過程:

1.將Url pull 到 Scheduler 接口

2.初始化組件:

創建HttpClient、創建線程池、通過Scheduler獲取Request集合

3.請求頁面

4.抽取數據 ,被@ExtractBy註釋的字段都會被PageModelExtractor類,注入對應數據

5.存放數據

存放的數據有二種方式獲取

一。Pipeline 接口   可在線程運行和結束時可獲取數據

二。AfterExtractor接口    單個線程結束時 可獲取數據,我使用這種方式保存數據

 

回到我們代碼本身,肯定不能將需要抓取的字段和接口實現放置到一起,但是數據要統一管理

Admin類正是爲此而設計

它繼承了擁有@ExtractBy註解的實體類,同時要求實現類需要實現AfterExtractor類的方法

Laws類圖:

在程序入口,需要繼承Admin類,實現afterProcess方法

 

數據拼裝

實現afterProcess方法後,爲我們傳過來一個Page對象,這裏面的數據爲:實體類@ExtractBy規則抓取的數據

當拿到數據後,就可以按照你自己的業務,進行處理了,比如像這樣

 

感想

隨着業務的增加,勢必需要監控爬蟲,實現前後端交互

現在有兩種監控方式

一.通過JConsole

二 繼承 SpiderStatusMXBean

這個還是比較不錯的,可以取到錯誤網頁 還支持啓動和停止

 

 

 

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