Golang在語言層級爲我們準備了天然的高併發支持,因此也寫個項目練練其併發使用。正好有位朋友想抓蛋殼網租房數據,我就趁這個機會寫一個go的併發版爬蟲項目。詳細代碼可移步至我github:https://github.com/slpslpslp/crawler。話不多說,進入正題。
項目結構
整體項目包含在crawler下,包括:
1.danke:目標網站。
- fetcher:處理url,得到返回結果。
- parser: 解析fetcher返回的結果
2.scheduler:任務調度器。
3.engine:實現Scheduler接口,建立工作引擎,中間件。
4.model:定義存儲數據類型
5.persist:對數據做持久化處理(本例實現的是存儲本地mysql)
6.main.go:項目入口
併發架構
注:該項目是我在油管上看到的一個教學視頻學到的,是位google大牛授課,其項目是爬取相親網站數據,上圖即爲其併發版架構(在我的項目項目代碼中,worker還要包括數據持久化,即除了Parser,Fetcher還有ItemSaverSql,圖上沒註明)。由於目前該課被無良商家舉報(爲了恰飯),所以也找不到其視頻源了。
整體:
- 將request傳遞給engine
- engine將request交給scheduler調度
- scheduler將request放入channel,然後由worker進行解析,將解析結果再放入channel,scheduler從channel中獲取
parseResult繼續調度任務
engine:
- 根據用戶配置WorkerCount,開啓多個goroutine實現併發
- 創建了供所有worker使用的channel
- 循環消費channel中的request,有就交給scheduler進行調度
scheduler:
- 持續將request放入channel,安排worker進行工作
爬蟲講解
蛋殼網的頁面佈局很簡單https://www.danke.com/room/sz/d.html,如下圖所示:
代碼areaList.go解析大的行政區下的子區域url信息,由於蛋殼網數據都是在返回的html信息上,沒有花裏胡哨的ajax之類的。所以這裏推薦使用htmlquery(真的很好用,誰用誰知道),獲取途徑
go get https://github.com/antchfx/htmlquery
代碼area.go解析子區域的房屋url信息,https://www.danke.com/room/sz/d南山區-b桃園.html,如下圖所示,獲取該頁的房屋列表中的每個入口url:
代碼rentDetail.go解析每個房屋的詳細信息,https://www.danke.com/room/1090110782.html,如下圖所示,獲取了紅色表框的各項屬性信息。
成果展示
golang爬蟲真的很棒!
補充:
- 該項目的可擴展性很好,你可以利用本項目框架去爬取其他的網站。
- 本例中只是爬取了每個子區域的第一頁房屋信息,沒有翻頁,如果想爬取所有數據,請自行完善。提示:在url後添加?page=n即可。
- 每個頁面解析腳本都應該寫測試單元(哎,太懶),因爲網站的頁面佈局往往更新很快,如果哪天測試不通過,針對性修改解析腳本即可。