網絡爬蟲按照系統結構和實現技術,大體能夠分爲如下幾種類型:通用網絡爬蟲、聚焦網絡爬蟲、增量式網絡爬蟲、深層網絡爬蟲。 實際的網絡爬蟲系統一般是幾種爬蟲技術相結合實現javascript
通用網絡爬蟲css
爬行對象從一些種子 URL 擴充到整個 Web,主要爲門戶站點搜索引擎和大型 Web 服務提供商採集數據html
對於爬行速度和存儲空間要求較高,對於爬行頁面的順序要求相對較低.java
通用網絡爬蟲適用於爲搜索引擎搜索普遍的主題正則表達式
聚焦網絡爬蟲算法
選擇性地爬行那些與預先定義好的主題相關頁面的網絡爬蟲,聚焦爬蟲只須要爬行與主題相關的頁面,極大地節省了硬件和網絡資源.編程
1.基於內容評價的爬行策略:DeBra將文本類似度的計算方法引入到網絡爬蟲中,提出了 Fish Search 算法,它將用戶輸入的查詢詞做爲主題,包含查詢詞的頁面被視爲與主題相關,其侷限性在於沒法評價頁面與主題相關度的高低 .跨域
2.基於連接結構評價的爬行策略 :Web 頁面做爲一種半結構化文檔,包含不少結構信息,可用來評價連接重要性。 PageRank 算法最初用於搜索引擎信息檢索中對查詢結果進行排序,也可用於評價連接重要性,具體作法就是每次選擇 PageRank 值較大頁面中的連接來訪問。 另外一個利用 Web結構評價連接價值的方法是 HITS 方法,它經過計算每一個已訪問頁面的 Authority 權重和 Hub 權重,並以此決定連接的訪問順序.瀏覽器
3.基於加強學習的爬行策略:Rennie 和 McCallum 將加強學習引入聚焦爬蟲,利用貝葉斯分類器,根據整個網頁文本和連接文本對超連接進行分類,爲每一個連接計算出重要性,從而決定連接的訪問順序服務器
4.基於語境圖的爬行策略:Diligenti 等人提出了一種經過創建語境圖(Context Graphs)學習網頁之間的相關度,訓練一個機器學習系統,經過該系統可計算當前頁面到相關 Web 頁面的距離,距離越近的頁面中的連接優先訪問。印度理工大學(IIT)和 IBM 研究中心的研究人員開發了一個典型的聚焦網絡爬蟲。 該爬蟲對主題的定義既不是採用關鍵詞也不是加權矢量,而是一組具備相同主題的網頁。 它包含兩個重要模塊:一個是分類器,用來計算所爬行的頁面與主題的相關度,肯定是否與主題相關;另外一個是淨化器,用來識別經過較少連接鏈接到大量相關頁面的中心頁面
增量式網絡爬蟲
對已下載網頁採起增量式更新和只爬行新產生的或者已經發生變化網頁的爬蟲,它可以在必定程度上保證所爬行的頁面是儘量新的頁面。和週期性爬行和刷新頁面的網絡爬蟲相比,增量式爬蟲只會在須要的時候爬行新產生或發生更新的頁面,並不從新下載沒有發生變化的頁面,可有效減小數據下載量,及時更新已爬行的網頁,減少時間和空間上的耗費,可是增長了爬行算法的複雜度和實現難度.
Deep Web 爬蟲
Web 頁面按存在方式能夠分爲表層網頁(Surface Web)和深層網頁(Deep Web,也稱 Invisible Web Pages 或 Hidden Web)。 表層網頁是指傳統搜索引擎能夠索引的頁面,以超連接能夠到達的靜態網頁爲主構成的 Web 頁面。Deep Web 是那些大部份內容不能經過靜態連接獲取的、隱藏在搜索表單後的,只有用戶提交一些關鍵詞才能得到的 Web 頁面。例如那些用戶註冊後內容纔可見的網頁就屬於 Deep Web。 2000 年 Bright Planet 指出:Deep Web 中可訪問信息容量是 Surface Web 的幾百倍,是互聯網上最大、發展最快的新型信息資源
Deep Web 爬蟲體系結構包含六個基本功能模塊 (爬行控制器、解析器、表單分析器、表單處理器、響應分析器、LVS 控制器)和兩個爬蟲內部數據結構(URL 列表、LVS 表)。 其中 LVS(Label Value Set)表示標籤/數值集合,用來表示填充表單的數據源
通用爬蟲原理:
圖示通用的網絡爬蟲的框架
基本工做流程以下:
1.首先選取一部分精心挑選的種子URL;
2.將這些URL放入待抓取URL隊列;
3.從待抓取URL隊列中取出待抓取在URL,解析DNS,而且獲得主機的ip,並將URL對應的網頁下載下來,存儲進已下載網頁庫中。此外,將這些URL放進已抓取URL隊列。
4.分析已抓取URL隊列中的URL,分析其中的其餘URL,而且將URL放入待抓取URL隊列,從而進入下一個循環。
互聯網的全部頁面分爲五個部分:
1.已下載未過時網頁
2.已下載已過時網頁:抓取到的網頁其實是互聯網內容的一個鏡像與備份,互聯網是動態變化的,一部分互聯網上的內容已經發生了變化,這時,這部分抓取到的網頁就已通過期了。
3.待下載網頁:也就是待抓取URL隊列中的那些頁面
4.可知網頁:尚未抓取下來,也沒有在待抓取URL隊列中,可是能夠經過對已抓取頁面或者待抓取URL對應頁面進行分析獲取到的URL,認爲是可知網頁。
5.還有一部分網頁,爬蟲是沒法直接抓取下載的。稱爲不可知網頁。
抓取策略
在爬蟲系統中,待抓取URL隊列是很重要的一部分。待抓取URL隊列中的URL以什麼樣的順序排列也是一個很重要的問題,由於這涉及到先抓取那個頁面,後抓取哪一個頁面。而決定這些URL排列順序的方法,叫作抓取策略。下面重點介紹幾種常見的抓取策略:
1.深度優先遍歷策略
深度優先遍歷策略是指網絡爬蟲會從起始頁開始,一個連接一個連接跟蹤下去,處理完這條線路以後再轉入下一個起始頁,繼續跟蹤連接。咱們如下面的圖爲例:
遍歷的路徑:A-F-G E-H-I B C D
2.寬度優先遍歷策略
寬度優先遍歷策略的基本思路是,將新下載網頁中發現的連接直接插入待抓取URL隊列的末尾。也就是指網絡爬蟲會先抓取起始網頁中連接的全部網頁,而後再選擇其中的一個連接網頁,繼續抓取在此網頁中連接的全部網頁。仍是以上面的圖爲例:
遍歷路徑:A-B-C-D-E-F G H I
3.反向連接數策略
反向連接數是指一個網頁被其餘網頁連接指向的數量。反向連接數表示的是一個網頁的內容受到其餘人的推薦的程度。所以,不少時候搜索引擎的抓取系統會使用這個指標來評價網頁的重要程度,從而決定不一樣網頁的抓取前後順序。
在真實的網絡環境中,因爲廣告連接、做弊連接的存在,反向連接數不能徹底等他我那個也的重要程度。所以,搜索引擎每每考慮一些可靠的反向連接數。
4.Partial PageRank策略
Partial PageRank算法借鑑了PageRank算法的思想:對於已經下載的網頁,連同待抓取URL隊列中的URL,造成網頁集合,計算每一個頁面的PageRank值,計算完以後,將待抓取URL隊列中的URL按照PageRank值的大小排列,並按照該順序抓取頁面。
若是每次抓取一個頁面,就從新計算PageRank值,一種折中方案是:每抓取K個頁面後,從新計算一次PageRank值。可是這種狀況還會有一個問題:對於已經下載下來的頁面中分析出的連接,也就是咱們以前提到的未知網頁那一部分,暫時是沒有PageRank值的。爲了解決這個問題,會給這些頁面一個臨時的PageRank值:將這個網頁全部入鏈傳遞進來的PageRank值進行彙總,這樣就造成了該未知頁面的PageRank值,從而參與排序。下面舉例說明:
5.OPIC策略策略
該算法實際上也是對頁面進行一個重要性打分。在算法開始前,給全部頁面一個相同的初始現金(cash)。當下載了某個頁面P以後,將P的現金分攤給全部從P中分析出的連接,而且將P的現金清空。對於待抓取URL隊列中的全部頁面按照現金數進行排序。
6.大站優先策略
對於待抓取URL隊列中的全部網頁,根據所屬的網站進行分類。對於待下載頁面數多的網站,優先下載。這個策略也所以叫作大站優先策略。
通常來說對咱們而言,須要抓取的是某個網站或者某個應用的內容,提取有用的價值,內容通常分爲兩部分,非結構化的文本,或結構化的文本。
HTML文本基本上是傳統爬蟲過程當中最多見的,也就是大多數時候會遇到的狀況,例如抓取一個網頁,獲得的是HTML,而後須要解析一些常見的元素,提取一些關鍵的信息。HTML其實理應屬於結構化的文本組織,可是又由於通常咱們須要的關鍵信息並不是直接能夠獲得,須要進行對HTML的解析查找,甚至一些字符串操做才能獲得,因此仍是歸類於非結構化的數據處理中。
常看法析方式以下:
如今的網頁樣式比較多,因此通常的網頁都會有一些CSS的定位,例如class,id等等,或者咱們根據常見的節點路徑進行定位,例如騰訊首頁的財經部分。
這裏id就爲finance,咱們用css選擇器,就是"#finance"就獲得了財經這一塊區域的html,同理,能夠根據特定的css選擇器能夠獲取其餘的內容。
XPATH是一種頁面元素的路徑選擇方法,利用Chrome能夠快速獲得,如:
copy XPATH 就能獲得——//*[@id="finance"]
正則表達式,用標準正則解析,通常會把HTML當作普通文本,用指定格式匹配當相關文本,適合小片斷文本,或者某一串字符,或者HTML包含javascript的代碼,沒法用CSS選擇器或者XPATH。
同正則表達式,更爲偷懶的方法,不建議使用。
例如一篇文章,或者一句話,咱們的初衷是提取有效信息,因此若是是滯後處理,能夠直接存儲,若是是須要實時提取有用信息,常見的處理方式以下:
根據抓取的網站類型,使用不一樣詞庫,進行基本的分詞,而後變成詞頻統計,相似於向量的表示,詞爲方向,詞頻爲長度。
天然語言處理,進行語義分析,用結果表示,例如正負面等。
結構化的數據是最好處理,通常都是相似JSON格式的字符串,直接解析JSON數據就能夠了,提取JSON的關鍵字段便可。
過去咱們常須要獲取的內容主要來源於網頁,通常來說,咱們決定進行抓取的時候,都是網頁上可看到的內容,可是隨着這幾年移動互聯網的發展,咱們也發現愈來愈多的內容會來源於移動App,因此爬蟲就不止侷限於必定要抓取解析網頁,還有就是模擬移動app的網絡請求進行抓取,因此這一部分我會分兩部分進行說明。
網頁內容通常就是指咱們最終在網頁上看到的內容,可是這個過程其實並非網頁的代碼裏面直接包含內容這麼簡單,因此對於不少新人而言,會遇到不少問題,好比:
明明在頁面用Chrome或者Firefox進行審查元素時能看到某個HTML標籤下包含內容,可是抓取的時候爲空。
不少內容必定要在頁面上點擊某個按鈕或者進行某個交互操做才能顯示出來。
因此對於不少新人的作法是用某個語言別人模擬瀏覽器操做的庫,其實就是調用本地瀏覽器或者是包含了一些執行JavaScript的引擎來進行模擬操做抓取數據,可是這種作法顯然對於想要大量抓取數據的狀況下是效率很是低下,而且對於技術人員自己而言也至關於在用一個盒子,那麼對於這些內容究竟是怎麼顯示在網頁上的呢?主要分爲如下幾種狀況:
這種狀況是最容易解決的,通常來說基本上是靜態網頁已經寫死的內容,或者動態網頁,採用模板渲染,瀏覽器獲取到HTML的時候已是包含全部的關鍵信息,因此直接在網頁上看到的內容均可以經過特定的HTML標籤獲得。
這種狀況是因爲雖然網頁顯示時,內容在HTML標籤裏面,可是實際上是因爲執行js代碼加到標籤裏面的,因此這個時候內容在js代碼裏面的,而js的執行是在瀏覽器端的操做,因此用程序去請求網頁地址的時候,獲得的response是網頁代碼和js的代碼,因此本身在瀏覽器端能看到內容,解析時因爲js未執行,確定找到指定HTML標籤下內容確定爲空,這個時候的處理辦法,通常來說主要是要找到包含內容的js代碼串,而後經過正則表達式得到相應的內容,而不是解析HTML標籤。
這種狀況是如今很常見的,尤爲是在內容以分頁形式顯示在網頁上,而且頁面無刷新,或者是對網頁進行某個交互操做後,獲得內容。那咱們該如何分析這些請求呢?這裏我以Chrome的操做爲例,進行說明:
因此當咱們開始刷新頁面的時候就要開始跟蹤全部的請求,觀察數據究竟是在哪一步加載進來的。而後當咱們找到核心的異步請求的時候,就只用抓取這個異步請求就能夠了,若是原始網頁沒有任何有用信息,也不必去抓取原始網頁了。
由於如今移動應用愈來愈多,不少有用信息都在App裏面,另外解析非結構化文本和結構文本對比而言,結構化文本會簡單多了,不一樣去找內容,去過多分析解析,全部既有網站又有App的話,推薦抓取App,大多數狀況下基本上只是一些JSON數據的API了。
那麼App的數據該如何抓取呢?通用的方法就是抓包,基本的作法就是電腦安裝抓包軟件,配置好端口,而後記下ip,手機端和電腦在同一個局域網裏面,而後在手機的網絡鏈接裏面設置好代理,這個時候打開App進行一些操做,若是有網絡數據請求,則都會被抓包軟件記下,就如上Chrome分析網絡請求同樣,你能夠看到全部的請求狀況,能夠模擬請求操做。這裏Mac上我推薦軟件Charles,Windows推薦Fiddler2。
具體如何使用,以後我再作詳述,可能會涉及到HTTPS證書的問題。
剛剛一直在寬泛的提到一些咱們須要找到請求,進行請求,對於請求只是一筆帶過,但請求是很重要的一部分,包括如何繞過限制,如何發送正確地數據,都須要對的請求,這裏就要詳細的展開說下請求,以及如何模擬請求。
咱們常說爬蟲其實就是一堆的HTTP請求,找到待爬取的連接,無論是網頁連接仍是App抓包獲得的API連接,而後發送一個請求包,獲得一個返回包(也有HTTP長鏈接,或者Streaming的狀況,這裏不考慮),因此核心的幾個要素就是:
在用Chrome進行網絡請求捕獲或者用抓包工具分析請求時,最重要的是弄清楚URL,請求方法,而後headers裏面的字段,大多數出問題就出在headers裏面,最常限制的幾個字段就是User-Agent, Referer, Cookie 另外Base Auth也是在headers裏面加了Autheration的字段。
請求內容也就是post時須要發送的數據,通常都是將Key-Value進行urlencode。返回包headers大多數會被人忽視,可能只獲得內容就能夠了,可是其實不少時候,不少人會發現明明url,請求方法還有請求包的內容都對了,爲何沒有返回內容,或者發現請求被限制,其實這裏大概有兩個緣由:
一個是返回包的內容是空的,可是在返回包的headers的字段裏面有個Location,這個Location字段就是告訴瀏覽器重定向,因此有時候代碼沒有自動跟蹤,天然就沒有內容了;
另一個就是不少人會頭疼的Cookie問題,簡單說就是瀏覽器爲何知道你的請求合法的,例如已登陸等等,其實就是可能你以前某個請求的返回包的headers裏面有個字段叫Set-Cookie,Cookie存在本地,一旦設置後,除非過時,通常都會自動加在請求字段上,因此Set-Cookie裏面的內容就會告訴瀏覽器存多久,存的是什麼內容,在哪一個路徑下有用,Cookie都是在指定域下,通常都不跨域,域就是你請求的連接host。
因此分析請求時,必定要注意前四個,在模擬時保持一致,同時觀察第五個返回時是否是有限制或者有重定向。
上述都是講的都是一些的基礎的知識,如今我就列一些比較常見的限制方式,如何突破這些限制抓取數據。
通常會有用戶受權的限制,會在headers的Autheration字段裏要求加入;
一般是在訪問連接時,必需要帶上Referer字段,服務器會進行驗證,例如抓取京東的評論;
會要求真是的設備,若是不加會用編程語言包裏自有User-Agent,能夠被辨別出來;
通常在用戶登陸或者某些操做後,服務端會在返回包中包含Cookie信息要求瀏覽器設置Cookie,沒有Cookie會很容易被辨別出來是僞造請求;
也有本地經過JS,根據服務端返回的某個信息進行處理生成的加密信息,設置在Cookie裏面;
請求headers裏面帶了gzip,返回有時候會是gzip壓縮,須要解壓;
通常都是在請求的數據包內容裏面會包含一些被javascript進行加密限制的信息,例如新浪微博會進行SHA1和RSA加密,以前是兩次SHA1加密,而後發送的密碼和用戶名都會被加密;
由於http的headers能夠自定義地段,因此第三方可能會加入了一些自定義的字段名稱或者字段值,這也是須要注意的。
真實的請求過程當中,其實不止上面某一種限制,多是幾種限制組合在一次,好比若是是相似RSA加密的話,可能先請求服務器獲得Cookie,而後再帶着Cookie去請求服務器拿到公鑰,而後再用js進行加密,再發送數據到服務器。因此弄清楚這其中的原理,而且耐心分析很重要。
首先大的地方,加入咱們想抓取某個數據源,咱們要知道大概有哪些路徑能夠獲取到數據源,基本上無外乎三種:
原則是能抓移動App的,最好抓移動App,若是有針對移動設備優化的網站,就抓針對移動設備優化的網站,最後考慮PC網站。由於移動App基本都是API很簡單,而移動設備訪問優化的網站通常來說都是結構簡單清晰的HTML,而PC網站天然是最複雜的了;
針對PC端網站和移動網站的作法同樣,分析思路能夠一塊兒講,移動App單獨分析。
首先是網站類的,使用的工具就是Chrome,建議用Chrome的隱身模式,分析時不用頻繁清楚cookie,直接關閉窗口就能夠了。
具體操做步驟以下:
分析異步請求,按照網絡列表,略過資源文件,而後點擊各個請求,觀察是否在返回時包含想要的內容,有幾個方法:
針對分析對請求的限制,思路是逆序方法。
而後是App類的,使用的工具是Charles,手機和電腦在一個局域網內,先用Charles配置好端口,而後手機設置代理,ip爲電腦的ip,端口爲設置的端口,而後若是手機上請求網絡內容時,Charles會顯示相應地請求,那麼就ok了,分析的大致邏輯基本一致,限制會相對少不少,可是也有幾種狀況須要注意:
通常來說在抓取大量數據,例如全網抓取京東的評論,微博全部人的信息,微博信息,關注關係等等,這種上十億到百億次設置千億次的請求必須考慮效率,否者一天只有86400秒,那麼一秒鐘要抓100次,一天也才864w次請求,也須要100多天才能到達十億級別的請求量。
涉及到大規模的抓取,必定要有良好的爬蟲設計,通常不少開源的爬蟲框架也都是有限制的,由於中間涉及到不少其餘的問題,例如數據結構,重複抓取過濾的問題,固然最重要的是要把帶寬利用滿,因此分佈式抓取很重要,接下來我會有一篇專門講分佈式的爬蟲設計,分佈式最重要的就是中間消息通訊,若是想要抓的越多越快,那麼對中間的消息系統的吞吐量要求也越高。
可是對於一些不太大規模的抓取就沒要用分佈式的一套,比較消耗時間,基本只要保證單機器的帶寬可以利用滿就沒問題,因此作好併發就能夠,另外對於數據結構也要有必定的控制,不少人寫程序,內存越寫越大,抓取愈來愈慢,可能存在的緣由就包括,一個是用了內存存一些數據沒有進行釋放,第二個可能有一些hashset的判斷,最後判斷的效率愈來愈低,好比用bloomfilter替換就會優化不少。
參考:http://www.cnblogs.com/wawlian/archive/2012/06/18/2553061.html
http://www.csdn.net/article/2015-11-13/2826205
百度百科