隨著BIG DATA大數(shù)據(jù)概念逐漸升溫,如何搭建一個能夠采集海量數(shù)據(jù)的架構(gòu)體系擺在大家眼前。如何能夠做到所見即所得的無阻攔式采集、如何快速把不規(guī)則頁面結(jié)構(gòu)化并存儲、如何滿足越來越多的數(shù)據(jù)采集還要在有限時間內(nèi)采集。這篇文章結(jié)合我們自身項目經(jīng)驗談一下。 我們來看一下作為人是怎么獲取網(wǎng)頁數(shù)據(jù)的呢? 1、打開瀏覽器,輸入網(wǎng)址url訪問頁面內(nèi)容。 從技術(shù)角度來說整個過程主要為 網(wǎng)絡(luò)訪問、扣取結(jié)構(gòu)化數(shù)據(jù)、存儲。我們看一下用java程序如何來實現(xiàn)這一過程。 import java.io.IOException; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.lang.StringUtils; public class HttpCrawler { public static void main(String[] args) { String content = null ; try { HttpClient httpClient = new HttpClient(); //1、網(wǎng)絡(luò)請求 GetMethod method = new GetMethod("http://www.baidu.com" ); int statusCode = httpClient.executeMethod(method); if (statusCode == HttpStatus. SC_OK) { content = method.getResponseBodyAsString(); //結(jié)構(gòu)化扣取 String title = StringUtils.substringBetween(content, "<title>" , "</title>" ); //存儲 System. out .println(title); } } catch (HttpException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { } } } 通過這個例子,我們看到通過httpclient獲取數(shù)據(jù),通過字符串操作扣取標題內(nèi)容,然后通過system.out輸出內(nèi)容。大家是不是感覺做一個爬蟲也還是蠻簡單呢。這是一個基本的入門例子,我們再詳細介紹怎么一步一步構(gòu)建一個分布式的適用于海量數(shù)據(jù)采集的爬蟲框架。 整個框架應(yīng)該包含以下部分,資源管理、反監(jiān)控管理、抓取管理、監(jiān)控管理??匆幌抡麄€框架的架構(gòu)圖:
一個好的采集框架,不管我們的目標數(shù)據(jù)在哪兒,只要用戶能夠看到都應(yīng)該能采集到。所見即所得的無阻攔式采集,無論是否需要登錄的數(shù)據(jù)都能夠順利采集。現(xiàn)在大部分社交網(wǎng)站都需要登錄,為了應(yīng)對登錄的網(wǎng)站要有模擬用戶登錄的爬蟲系統(tǒng),才能正常獲取數(shù)據(jù)。不過社會化網(wǎng)站都希望自己形成一個閉環(huán),不愿意把數(shù)據(jù)放到站外,這種系統(tǒng)也不會像新聞等內(nèi)容那么開放的讓人獲取。這些社會化網(wǎng)站大部分會采取一些限制防止機器人爬蟲系統(tǒng)爬取數(shù)據(jù),一般一個賬號爬取不了多久就會被檢測出來被禁止訪問了。那是不是我們就不能爬取這些網(wǎng)站的數(shù)據(jù)呢?肯定不是這樣的,只要社會化網(wǎng)站不關(guān)閉網(wǎng)頁訪問,正常人能夠訪問的數(shù)據(jù),我們也能訪問。說到底就是模擬人的正常行為操作,專業(yè)一點叫“反監(jiān)控”。 那一般網(wǎng)站會有什么限制呢? 一定時間內(nèi)單IP訪問次數(shù),沒有哪個人會在一段持續(xù)時間內(nèi)過快訪問,除非是隨意的點著玩,持續(xù)時間也不會太長??梢圆捎么罅坎灰?guī)則代理IP來模擬。 一定時間內(nèi)單賬號訪問次數(shù),這個同上,正常人不會這么操作??梢圆捎么罅啃袨檎5馁~號,行為正常就是普通人怎么在社交網(wǎng)站上操作,如果一個人一天24小時都在訪問一個數(shù)據(jù)接口那就有可能是機器人了。 如果能把賬號和IP的訪問策略控制好了,基本可以解決這個問題了。當然對方網(wǎng)站也會有運維會調(diào)整策略,說到底這是一個戰(zhàn)爭,躲在電腦屏幕后的敵我雙方,爬蟲必須要能感知到對方的反監(jiān)控策略進行了調(diào)整,通知管理員及時處理。未來比較理想應(yīng)該是通過機器學習算法自動完成策略調(diào)整,保證抓取不間斷。 整個抓取使用了 xpath、正則表達式、消息中間件、多線程調(diào)度框架(參考)。xpath 是一種結(jié)構(gòu)化網(wǎng)頁元素選擇器,支持列表和單節(jié)點數(shù)據(jù)獲取,他的好處可以支持規(guī)整網(wǎng)頁數(shù)據(jù)抓取。我們使用的是google插件 XPath Helper,這個玩意可以支持在網(wǎng)頁點擊元素生成xpath,就省去了自己去查找xpath的功夫,也便于未來做到所點即所得的功能。正則表達式補充xpath抓取不到的數(shù)據(jù),還可以過濾一些特殊字符。消息中間件,起到抓取任務(wù)中間轉(zhuǎn)發(fā)的目的,避免抓取和各個需求方耦合。比如各個業(yè)務(wù)系統(tǒng)都可能抓取數(shù)據(jù),只需要向消息中間件發(fā)送一個抓取指令,抓取平臺抓完了會返回一條消息給消息中間件,業(yè)務(wù)系統(tǒng)在從消息中間件收到消息反饋,整個抓取完成。多線程調(diào)度框架之前提到過,我們的抓取平臺不可能在同一時刻只抓一個消息的任務(wù);也不可能無限制抓取,這樣資源會耗盡,導致惡性循環(huán)。這就需要使用多線程調(diào)度框架來調(diào)度多線程任務(wù)并行抓取,并且任務(wù)的數(shù)量,保證資源的消耗正常。 不管怎么模擬總還是會有異常的,這就需要有個異常處理模塊,有些網(wǎng)站訪問一段時間需要輸入驗證碼,如果不處理后續(xù)永遠返回不了正確數(shù)據(jù)。我們需要有機制能夠處理像驗證碼這類異常,簡單就是有驗證碼了人為去輸入,高級一些可以破解驗證碼識別算法實現(xiàn)自動輸入驗證碼的目的。 擴展一下 :所見即所得我們是不是真的做到?規(guī)則配置也是個重復的大任務(wù)?重復網(wǎng)頁如何不抓取? 1、有些網(wǎng)站利用js生成網(wǎng)頁內(nèi)容,直接查看源代碼是一堆js。 可以使用mozilla、webkit等可以解析瀏覽器的工具包解析js、ajax,不過速度會有點慢。 背景:如果我們需要抓取的網(wǎng)站很多,那如果靠可視化配置需要耗費大量的人力,這是個成本。并且這個交給不懂html的業(yè)務(wù)去配置準確性值得考量,所以最后還是需要技術(shù)做很多事情。那我們能否通過技術(shù)手段可以幫助生成規(guī)則減少人力成本,或者幫助不懂技術(shù)的業(yè)務(wù)準確的把數(shù)據(jù)扣取下來并大量復制。 方案:先對網(wǎng)站分類,比如分為新聞、論壇、視頻等,這一類網(wǎng)站的網(wǎng)頁結(jié)構(gòu)是類似的。在業(yè)務(wù)打開需要扣取的還沒有錄入我們規(guī)則庫的網(wǎng)頁時,他先設(shè)定這個頁面的分類(當然這個也可以機器預先判斷,他們來選擇,這一步必須要人判斷下),有了分類后,我們會通過“統(tǒng)計學、可視化判斷”識別這一分類的字段規(guī)則,但是這個是機器識別的規(guī)則,可能不準確,機器識別完后,還需要人在判斷一下。判斷完成后,最后形成規(guī)則才是新網(wǎng)站的規(guī)則 7、對付重復的網(wǎng)頁,如果重復抓取會浪費資源,如果不抓需要一個海量的去重判斷緩存。判斷抓不抓,抓了后存不存,并且這個緩存需要快速讀寫。常見的做法有bloomfilter、相似度聚合、分類海明距離判斷。 目前這樣的框架搭建起來基本可以解決大量的抓取需求了。通過界面可以管理資源、反監(jiān)控規(guī)則、網(wǎng)頁扣取規(guī)則、消息中間件狀態(tài)、數(shù)據(jù)監(jiān)控圖表,并且可以通過后臺調(diào)整資源分配并能動態(tài)更新保證抓取不斷電。不過如果一個任務(wù)的處理特別大,可能需要抓取24個小時或者幾天。比如我們要抓取一條微博的轉(zhuǎn)發(fā),這個轉(zhuǎn)發(fā)是30w,那如果每頁線性去抓取耗時肯定是非常慢了,如果能把這30w拆分很多小任務(wù),那我們的并行計算能力就會提高很多。不得不提的就是把大型的抓取任務(wù)hadoop化,廢話不說直接上圖: 今天先寫到這里,后續(xù)再介紹下 日均千萬大型采集項目實戰(zhàn)。 |
|