【重磅開源】Hawk-數據抓取工具:簡明教程

Hawk: Advanced Crawler& ETL tool written in C#/WPF

1.軟件介紹

Hawk3已經發布,本文的不少信息已經不完整或過時,全部更新信息和下載地址均可參考下面的連接:html

https://github.com/ferventdesert/Hawk前端


HAWK是一種數據採集和清洗工具,依據GPL協議開源,可以靈活,有效地採集來自網頁,數據庫,文件, 並經過可視化地拖拽,
快速地進行生成,過濾,轉換等操做。其功能最適合的領域,是爬蟲和數據清洗。python

Hawk的含義爲「鷹」,可以高效,準確地捕殺獵物。git

HAWK使用C# 編寫,其前端界面使用WPF開發,支持插件擴展。經過圖形化操做,可以快速創建解決方案。程序員

GitHub地址:https://github.com/ferventdesert/Hawkgithub

其Python等價的實現是etlpy:正則表達式

http://www.cnblogs.com/buptzym/p/5320552.html算法

筆者專門爲其開發的工程文件已公開在GitHub:數據庫

https://github.com/ferventdesert/Hawk-Projects後端

使用時,點擊文件,加載工程便可加載。

編譯路徑在:
Hawk.Core\Hawk.Core.sln

2.gif-3330.9kB

以獲取大衆點評的全部北京美食爲例,使用本軟件可在10分鐘內完成配置,在1小時以內自動並行抓取所有內容,並能監視子線程工做狀況。而手工編寫代碼,即便是使用python,一個熟練的程序員也可能須要一天以上:

1.gif-1001.8kB

視頻演示,複雜度由小到大:

鏈家二手房

微信公共平臺

大衆點評-北京美食

2.界面和組件介紹

2.1 界面介紹

軟件採用相似Visual Studio和Eclipse的Dock風格,全部的組件均可以懸停和切換。包括如下核心組件:

QQ截圖20160501105541.jpg-85.3kB

  • 左上角區域:主要工做區,可模塊管理。
  • 下方: 輸出調試信息,和任務管理,監控一項任務完成的百分比。
  • 右上方區域: 屬性管理器,能對不一樣的模塊設置屬性。
  • 右下方區域: 顯示當前已經加載的全部數據表和模塊。

2.2 數據管理

可以添加來自不一樣數據源的鏈接器, 並對數據進行加載和管理:

QQ截圖20160501105629.jpg-13.9kB

在空白處,點擊右鍵,可增長新的鏈接器。在鏈接器的數據表上,雙擊可查看樣例,點擊右鍵,能夠將數據加載到內存中。也能夠選擇加載虛擬數據集,此時系統會維護一個虛擬集合, 當上層請求分頁數據時, 動態地訪問數據庫, 從而有效提高性能。

2.3 模塊管理

目前系統僅僅提供了兩個模塊: 網頁採集器和數據清洗ETL, 雙擊便可加載一個新的模塊。

QQ截圖20160501105646.jpg-6.8kB

以前配置好的模塊,能夠保存爲任務, 雙擊可加載一個已有任務:

QQ截圖20160501105700.jpg-10.5kB

2.4 系統狀態管理

當加載了數據集或模塊時,在系統狀態管理中,就可對其查看和編輯:
點擊右鍵,能夠對數據集進行刪除,修更名稱等。也能夠將數據集拖拽到下方的圖標上,如拖到回收站,便可刪除該模塊。
雙擊數據集或模塊,可查看模塊的內容。 將數據集拖拽到數據清洗( 數據視圖的下方第一個圖標),可直接對本數據集作數據清洗。

QQ截圖20160501105734.jpg-14.6kB

3.網頁採集器

3.1 原理(建議閱讀)

網頁採集器的功能是獲取網頁中的數據(廢話)。一般來講,目標多是列表(如購物車列表),或是一個頁面中的固定字段(如JD某商品的價格和介紹,在頁面中只有一個)。所以須要設置其讀取模式。傳統的採集器須要編寫正則表達式,但方法過度複雜。若是認識到html是一棵樹,只要找到了承載數據的節點便可。XPath就是一種在樹中描述路徑的語法。指定XPath,就能搜索到樹中的節點。

QQ截圖20160501105743.jpg-20kB

手工編寫XPath也很複雜,所以軟件能夠經過關鍵字,自動檢索XPath,提供關鍵字,軟件就會從樹中遞歸搜索包含該數據的葉子節點。所以關鍵字最好是在頁面中獨一無二的。

如上圖所示,只要提供「北京」和「42」這兩個關鍵字,就能找到parent節點, 進而獲取div[0]和div1這兩個列表元素。經過div[0]和div1兩個節點的比較,咱們就能自動發現相同的子節點(name,mount)和不一樣的節點(北京:上海,37:42)。相同的節點會保存爲屬性名,不一樣的節點爲屬性值。可是,不能提供北京和37,此時,公共節點是div[0], 這不是列表。

軟件在不提供關鍵字的狀況下,也能經過html文檔的特徵,去計算最多是列表父節點(如圖中的parent)的節點,但當網頁特別複雜時,猜想可能會出錯,因此須要至少提供兩個關鍵字( 屬性)。

本算法原理是原創的,可查看源碼或留言交流。

3.2 基本列表

咱們以爬取鏈家二手房爲例,介紹網頁採集器的使用。首先雙擊圖標,加載採集器:

QQ截圖20160501121116.jpg-17.2kB

在最上方的地址欄中,輸入要採集的目標網址,本次是http://bj.lianjia.com/ershoufang/。並點擊刷新網頁。此時,下方展現的是獲取的html文本。原始網站頁面以下:

因爲軟件不知道到底要獲取哪些內容,所以須要手工給定幾個關鍵字, 讓Hawk搜索關鍵字, 並獲取位置。

QQ截圖20160501121150.jpg-88kB

以上述頁面爲例,經過檢索820萬和51789(單價,每次採集時都會有所不一樣),咱們就能經過DOM樹的路徑,找出整個房源列表的根節點。

下面是實際步驟

QQ截圖20160501121344.jpg-21.6kB

因爲要抓取列表,因此讀取模式選擇List。 填入搜索字符700, 發現可以成功獲取XPath, 編寫屬性爲「總價」 ,點擊添加字段,便可添加一個屬性。相似地,再填入30535,設置屬性名稱爲「單價」,便可添加另一個屬性。

若是發現有錯誤,可點擊編輯集合, 對屬性進行刪除,修改和排序。

你能夠相似的將全部要抓取的特徵字段添加進去,或是直接點擊手氣不錯,系統會根據目前的屬性,推測其餘屬性:

QQ截圖20160501121405.jpg-138.5kB

屬性的名稱是自動推斷的,若是不滿意,能夠修改列表第一列的屬性名, 在對應的列中敲鍵盤回車提交修改。以後系統就會自動將這些屬性添加到屬性列表中。

工做過程當中,可點擊提取測試 ,隨時查看採集器目前的可以抓取的數據內容。這樣,一個鏈家二手房的網頁採集器便可完成。可屬性管理器的上方,能夠修改採集器的模塊名稱,這樣就方便數據清洗 模塊調用該採集器。

4. 數據清洗

數據清洗模塊,包括幾十個子模塊, 這些子模塊包含四類:生成, 轉換, 過濾和執行

QQ截圖20160501121511.jpg-31.3kB

4.0 原理(可跳過)

4.0.1 C#版本的解釋

數據清洗的本質是動態組裝Linq,其數據鏈爲IEnumerable<IFreeDocument>IFreeDocumentIDictionary<string, object>
接口的擴展。 Linq的Select函數可以對流進行變換,在本例中,就是對字典不一樣列的操做(增刪改),不一樣的模塊定義了一個完整的Linq
流:

result= source.Take(mount).where(d=>module0.func(d)).select(d=>Module1.func(d)).select(d=>Module2.func(d))….

藉助於C#編譯器的恩賜, Linq能很方便地支持流式數據,即便是巨型集合(上億個元素),也可以有效地處理。

4.0.2 Python版本的解釋

因爲Python沒有Linq, 所以組裝的是生成器(generator), 對生成器進行操做,便可定義出相似Linq的完整鏈條:

for tool in tools:
    generator = transform(tool, generator)

詳細源代碼,能夠參考Github上的開源項目https://github.com/ferventdesert/etlpy/

4.1 以鏈家爲例的抓取

4.1.1構造url列表

在3.1節介紹瞭如何實現一個頁面的採集,但如何採集全部二手房數據呢? 這涉及到翻頁。

QQ截圖20160501121520.jpg-3.1kB

仍是以鏈家爲例,翻頁時,咱們會看到頁面是這樣變換的:

http://bj.lianjia.com/ershoufang/pg2/
http://bj.lianjia.com/ershoufang/pg3/
…

所以,須要構造一串上面的url. 聰明的你確定會想到, 應當先生成一組序列, 從1到100(假設咱們只抓取前100頁)。

  1. 雙擊數據清洗ETL左側的搜索欄中搜索生成區間數, 將該模塊拖到右側上方的欄目中:

QQ截圖20160501121554.jpg-29.8kB

  1. 在右側欄目中雙擊生成區間數,可彈出設置窗口, 爲該列起名字(id), 最大值填寫爲100,生成模式默認爲Append:
    爲何只顯示了前20個? 這是程序的虛擬化機制, 並無加載所有的數據,可在ETL屬性的調試欄目中,修改採樣量(默認爲20)。
  2. 將數字轉換爲url, 熟悉C#的讀者,能夠想到string.format, 或者python的%符號:搜索合併多列,並將其拖拽到剛纔生成的id列, 編寫format爲下圖的格式,便可將原先的數值列變換爲一組url

QQ截圖20160501121916.jpg-22.9kB

(若是須要多個列合併爲一個列, 則在「其餘項」 欄目中填寫其餘列的列名,用空格分割, 並在format中用{1},{2}..等表示)
(因爲設計的問題,數據查看器的寬度不超過150像素,所以對長文本顯示不全,能夠在右側屬性對話框點擊查看樣例, 彈出的編輯器可支持拷貝數據和修改列寬。

4.1.2 使用配置好的網頁採集器

生成這串URL以後,咱們便可將剛纔已經完成的網頁採集器與這串url進行合併。

拖拽從爬蟲轉換到當前的url,雙擊該模塊:將剛纔的網頁採集器的名稱, 填入爬蟲選擇 欄目中。

以後,系統就會轉換出爬取的前20條數據:

QQ截圖20160501122007.jpg-127.3kB

能夠看到, 數據中「屬性3」 列包含html轉義符, 拖拽html字符轉義,到屬性3列,便可自動轉換全部轉義符。

QQ截圖20160501122026.jpg-81.4kB

若是要修改列名,在最上方的列名上直接修改, 點擊回車便可修更名字。

where(面積)列中包含數字,想把數字提取出來,能夠將提取數字模塊拖拽到該列上,全部數字便可提取出來。

相似地,能夠拖拽字符分割正則分割 到某一列,從而分割文本和替換文本。此處再也不贅述。

有一些列爲空,能夠拖拽空對象過濾器 到該列,那麼該列爲空的話會自動過濾這一行數據。

4.1.4 保存和導出數據

須要保存數據時,能夠選擇寫入文件,或者是臨時存儲(本軟件的數據管理器),或是數據庫。所以能夠將「執行」 模塊, 拖入清洗鏈的後端:
寫入數據表到任意一列, 並填入新建表名(如鏈家二手房)

QQ截圖20160501122057.jpg-32kB

下圖是此次操做的全部子模塊列表:

QQ截圖20160501122110.jpg-14.1kB

以後,便可對整個過程進行操做:

選擇串行模式並行模式, 並行模式使用線程池, 可設定最多同時執行的線程數(最好不要超過100)。推薦使用並行模式,

QQ截圖20160501122136.jpg-12.5kB

點擊執行按鈕,便可在任務管理視圖中採集數據。

QQ截圖20160501122147.jpg-10.5kB

以後,在數據管理的數據表鏈家二手房上點擊右鍵, 選擇另存爲, 導出到Excel,Json等,便可將原始數據導出到外部文件中。

QQ截圖20160501122153.jpg-3.8kB

相似的, 你能夠在清洗流程中拖入執行器,則保存的是中間過程,也能夠在結尾拖入多個執行器,這樣就能同時寫入數據庫或文件, 從而得到了極大的靈活性。

4.1.5 保存任務

在右下角的算法視圖中的任意模塊上點擊右鍵,保存任務,便可在任務視圖中保存新任務(任務名稱與當前模塊名字一致),下次可直接加載便可。若是存在同名任務, 則會對原有任務進行覆蓋。
算法視圖的空白處,點擊保存全部模塊,會批量保存全部的任務。

QQ截圖20160501122208.jpg-12.1kB

你能夠將一批任務,保存爲一個工程文件(xml),並在以後將其加載和分發。

5.總結

上文以抓取房地產網站鏈家爲例,介紹了軟件的總體使用流程。固然,Hawk功能遠遠不限於這些。以後咱們將經過一系列文章來介紹其使用方法。

值得提醒的是,因爲軟件功能在不斷地升級,可能會出現視頻和圖片與軟件中不一致的狀況,所以全部的介紹和功能以軟件的實際功能爲準。

相關文章
相關標籤/搜索