Hawk-數據抓取工具


Hawk-數據抓取工具:簡明教程

 

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

1.軟件介紹

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

Hawk的含義為“鷹”,能夠高效,准確地捕殺獵物。

HAWK使用C# 編寫,其前端界面使用WPF開發,支持插件擴展。通過圖形化操作,能夠快速建立解決方案。

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

其Python等價的實現是etlpy:

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

筆者專門為其開發的工程文件已公開在GitHub:

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

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

不想編譯的話,可執行文件在:

https://github.com/ferventdesert/Hawk/tree/master/Versions

編譯路徑在:
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>。 IFreeDocument是 IDictionary<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功能遠遠不限於這些。之后我們將通過一系列文章來介紹其使用方法。

值得提醒的是,由於軟件功能在不斷地升級,可能會出現視頻和圖片與軟件中不一致的情況,因此所有的介紹和功能以軟件的實際功能為准。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM