網頁蒐集系統

自1994年萬維網出現後,互聯網上的網頁數量就呈指數級生長,到目前爲止,短短二十餘年,互聯網上就有成百上千億網頁。如何在這海量的網頁中搜索下載具備對特定場景有價值的網頁?使用什麼樣的策略能保證網頁不會出現重複?如何保證爬蟲程序的高併發爬取?如何在網頁中提取關鍵點等等問題,這是本篇博客重點描述的內容。php

1.1 萬維網結構分析

把萬維網看做是一個相互連通的連通圖,每一個網頁看做一個節點,連接看做爲邊,其中任意一個網頁可被其它網頁所連接,這種連接叫「反向連接」,這個網頁也能夠連接到其它網頁,這種連接就叫「正向連接」。遍歷網頁的有兩種方向,正向遍歷和反向遍歷,其中正向遍歷是按正向連接的方向進行遍歷網頁,而反向遍歷則是按反向連接的方向遍歷網頁。html

研究者經實驗發現,不管是正向遍歷仍是反向遍歷,表現出來的是大相徑庭的效果。要麼遍歷到不多的一個網頁集合,要麼是爆炸性的遍歷到上億的網頁,從實驗結果中,研究者發現,萬維網具備蝴蝶結型結構,以下圖所示。nginx

圖 1-1萬維網的蝴蝶結型結構[1]算法

此結構分爲左中右三部分,其中左部的成爲「目錄型網頁」,即常說的導航網頁,今後部分出發開始採用正向遍歷,可至少能遍歷到所有網頁的3/4,而採用反向遍歷,則只能遍歷到不多的一部分;中部的網頁則是彼此連通的網頁,此部分無論是採用正向仍是反向,都大體可遍歷到所有網頁的3/4;右部的網頁稱爲「權威網頁」,這部分網頁被中部網頁所指向,這部分的網頁「承認度」高,被大部分網頁所引用,很明顯,此部分網頁的遍歷與左部網頁的遍歷呈對稱型;而「蝴蝶」的「須腳」部分,此部分的網頁表現爲從左部連接到其它網頁,或者從左部或右部直接連接到右部,以及少部分與中部、左部或右部都沒有連接,在此部分網頁出發,無論採用正向遍歷或是反向遍歷都只能遍歷到有限的不多一部分網頁。sql

通過以上分析,咱們能夠得出,爬蟲應儘量從蝴蝶型的左部出發,或從中部的網頁開始遍歷。數據庫

1.2 網絡爬蟲

網絡爬蟲是網頁蒐集系統最重要的一部分之一,它是搜索引擎工做的基礎。本節中將介紹網絡爬蟲的基礎概念、分佈式爬蟲的架構、一些爬取網頁的策略以及robots協議等。數組

1.2.1 爬蟲概念

爬蟲,它經過下載一個網頁,分析其中的連接,繼而去訪問其它連接指向的網頁,周而復始進行,直到磁盤滿或人工干預,爬蟲的功能歸結爲兩點:下載網頁和發現URL。瀏覽器

爬蟲訪問網頁和瀏覽器有着相同的方式,一樣也都是都是使用HTTP協議和網頁服務器交互。流程主要以下[2]緩存

1.   客戶端程序(爬蟲程序)鏈接到一個DNS服務器上。DNS服務器將主機名轉換呈IP地址,由於爬蟲程序會頻繁的查詢DNS服務器,因此可能會形成相似於拒絕服務攻擊(DOS)的反作用,因此在不少爬蟲程序實現中都會增長DNS緩存,以減小不少沒必要要的DNS服務器查詢,在商業搜索引擎中,通常都會搭建本身的DNS服務器。
2.   創建鏈接後,客戶端會發送一個HTTP請求給網絡服務器,以請求一個頁面。常見的HTTP請求是GET請求,如:
GET http://www.sina.com.cn/index.htmlHTTP/1.1
該命令表示請求服務器使用HTTP 1.1協議規範1.1版本,將頁面www.sina.com.cn/index.html頁面返回給客戶端。固然客戶端也可以使用POST命令訪問網絡服務器。一樣,爬蟲程序也會頻繁的使用GET命令,而使用該命令後會將頁面全部內容返回給客戶端,在網頁重訪(由於不少網頁會更新,因此需重訪網頁以獲得最新的網頁內容)時,嘗試用HEAD命令訪問服務器,該命令則是要求將網頁的head部分返回給客戶端,該head部分包含了網頁的最後更新時間(Last-Modified)字段,在比對數據庫中該網頁的此字段後,就可避免大量未更新網頁的下載。
3.   分析網頁中的URL連接,將它們插入一個隊列中,同時提取網頁中的重要內容存儲到數據庫中。隊列的主要特色是FIFO,每次將新發現的URL插到隊列尾部,而後取得從隊列頭部取得下一待訪問URL,這樣循環反覆進行,直到隊列爲空,這即是常說的寬度優先遍歷。

通過以上三個步驟便實現了一個簡單的網絡爬蟲。但其中還有不少問題,例如:服務器

1)  如何避免訪問重複URL(訪問重複URL將會致使無限循環);

2)  爬蟲需遵循的Robots協議等;

3)  如何避免因頻繁的訪問致使網絡服務器「發怒」;

4)  如何設計本課題中電子產品頁面採集策略;

5)  分類器;

6)  網頁格式的轉換問題;

7)  如何設計網頁的存儲結構以及選擇什麼樣的數據庫存儲海量網頁頁面;

8)  由於網頁也會由於過時,如何設計重訪網頁策略;

9)  如何高效率地爬取網頁(將在1.3節中講解);

URL重複避免

避免URL重訪是一個很關鍵的問題,若是URL重複訪問,必然會致使一個無限的遞歸訪問,直至資源窮盡。通常的策略是維護兩個表:visited_table和unvisited_table,visited_table表示已訪問URL的表,而unvisited_table至關於一個「任務池」,爬蟲不斷地從unvisited_table中取得待訪問URL,這樣就避免了網頁的重複訪問。工做步驟以下:

1.   爲爬蟲線程添加一個control進程,此進程主要功能是控制爬蟲爬取網頁,維護兩個URL表等,至關於一個控制器。

2.   爬蟲每次爬取網頁時,從unvisited_table中取得URL,下載網頁後,對網頁進行一系列處理插入到數據庫中,同時分析網頁中的連接,將連接遞交到control進程。

3.   control進程在獲得爬蟲URL連接後,比對visited_table,看其中是否存在,若不存在,則將該URL插入到unvisited_table中,同時會返回一個URL給爬蟲,爬蟲繼續爬取該URL。

visited_table可以使用一個hash函數,則visited_table是一個bit數組。由於hash函數面臨着衝突問題,因此若是有更高的精確要求,可改用Bloom Filter,Bloom Filter的原理很簡單,它使用多個不一樣hash函數來斷定,例如,初始化bit數組全部位爲0,對於一個URL1,使用多個不一樣的hash函數計算後,將bit數組相應位置1,當判斷URL2是否已訪問時,對URL2一樣使用hash函數計算,若是計算後,相應的bit數組爲0,則表示該URL未訪問,不然,若bit數組中其中任何一位爲1,則表示該URL已訪問, 具體的證實可參考參考文獻。


圖1-2 Bloom Filter工做原理示例圖

正如圖1-2所示,對URL2使用Bloom Filter時,有一個bit位已置1,故表示該URL已訪問過。


避免網絡服務器「發怒」

爲什麼網絡服務器會「發怒」?網絡服務器承受不住爬蟲的頻繁快速的訪問,若是該網絡服務器性能不是很強大,它將花費全部時間處理網絡爬蟲的請求,而不會去處理真實用戶的請求,因而它可能將該爬蟲看做是DOS攻擊,從而禁止爬蟲的IP,因此應該避免網絡服務器的「發怒」,如何處理呢?一般是在爬蟲訪問該服務器後,爬蟲應該等待幾秒,從而給網絡服務器足夠的時間去處理其它請求,同時爬蟲也應該遵照robots協議。

robots協議

robots協議是Web站點和搜索引擎爬蟲交互的一種方式,網絡管理員將一個robots.txt的文件放在網站的根目錄上,例如https://www.google.com/robots.txt.


其中User-agent表示爬蟲類型(如上圖中的*表示全部爬蟲),Disallow表示禁止該爬蟲爬取的目錄,Allow表示容許爬取的頁面或目錄,因此在具體實現搜索引擎時,還應該增長一個robots協議分析模塊,嚴格遵照robots協議的規定只抓取Web主機容許訪問的目錄和網頁。

 

頁面採集策略

針對垂直搜索策略有如下兩種:

1.   對整個互聯網頁面蒐集下載,而後去除不相關頁面。此種方法的缺點是將會佔用大量的磁盤空間和帶寬,在具體實現中不可取。

2.   第二種方式是基於這樣一個事實:一個話題頁面每每存在相關主題頁面。其中錨文本的做用相當重要,它指示了相關連接的主題,因此在實際應用中,一個特定話題的多個權威頁面都被用做種子頁面。

文本分類技術。爬蟲使用分類器來肯定該頁面是否與給定的主題相關。經常使用樸素貝葉斯分類器或支持向量機等。下面將簡要講解這兩種分類器。

分類器

1.   樸素貝葉斯分類器

 

2.   支持向量機

 

網頁格式轉換

計算機中文本是以幾百種相互之間不兼容的格式進行存儲的。標準的文本格式包括原始文本、HTML、XML、Word以及PDF等等,若是不以正確的方式去處理,每每會出現亂碼的狀況,因此須要一個工具,在處理到一個新文本格式時,能將它轉換成通用的格式,在本課題中,則將它轉換到HTML格式便可。計算機存儲文件時,還有個問題是編碼問題,此問題的通用解決方案是查看網頁頭部的編碼格式,而後以相應的編碼格式讀取分析。

因此,當下載到一篇網頁後,首先查看頭部信息:查看文本格式和編碼格式,而後以相應的方法去處理便可。

網頁存儲問題

網頁的存儲面臨兩個問題:以什麼樣的格式存儲網頁?使用什麼樣的數據庫?

1.   首先處理存儲網頁的格式問題。若是將下載後的網頁直接存儲到數據庫,則有兩個問題:

1)  每一個網頁平均約有70K,在磁盤上傳輸70K的數據會很快,可能只須要不到1毫秒的時間,但在查找時,卻可能須要10毫秒,因此在打開這些零散小文件來讀取文檔時,需大量的時間開銷,一種好的解決方案是將多個文檔存儲在一個單獨的文件中,以一種自自定義的格式進行存儲,例如:

<DOC>
<DOCNO>102933432<DOCNO>
<DOCHEADER>
http://www.sina.com.cn/index.htmltext/html 440
http/1.1200 ok
IP:221.236.31.210
Date:Wed, 02 Jan 2016 09:32:23 GMT
Content-Encoding: gzip
Last-Modified: Tue, 03 Jan 2016 01:52:09GMT
Server: nginx
Content-Length: 119201
</DOCHEADER>
<!DOCTYPE html>
<html>
<head>
   <meta http-equiv="Content-type" content="text/html;charset=utf-8" />
   <meta http-equiv="X-UA-Compatible"content="IE=edge" />
             <title>新浪首頁</title>
……
</html>
</DOC>
<DOC>
<DOCNO>102933433<DOCNO>
<DOCHEADER>
……
</DOCHEADER>
……
</DOC>


例子中:

<DOC></DOC>標記了一篇網頁的內容,其中包括了<DOCNO>、<DOCHEADER>和網頁原始內容;<DOCNO></DOCNO>標記網頁的編號;,<DOCHEADER></DOCHEADER>標記了網頁的頭部信息,此部分大多數由網絡服務器返回;剩餘部分爲網頁內容。

2) 若是數據量過大,經常會將存儲的文件進行壓縮以節省磁盤空間。

2. 第二個問題是存儲系統的選擇。存儲系統能夠選擇關係數據庫和NoSQL數據庫,在主要的搜索引擎中,不多使用傳統的關係數據庫來存儲文檔,由於大量的文檔數據將會壓垮關係數據庫系統,非關係數據庫的強大分佈式能力,海量數據存儲能力,故障恢復能力等等促使搜索引擎中偏向於使用非關係數據庫。在本課題中能夠選擇MongoDB或BigTable等數據庫系統,它們一樣也有相似於Mysql強大的社區支持,開源免費等特色。

頁面重訪機制

由於不少網頁會更新,因此需重訪網頁以獲得最新的網頁內容,來保持網頁庫中內容的「與時俱進」,而不一樣的網站更新頻率也不一樣,這就要對網頁變化進行分析建模。

研究代表,網頁的變化能夠歸結爲泊松過程模型,具體可見參考文獻。

常見的重訪策略有兩種:

1)統一的重訪策略:爬蟲以一樣的頻率重訪已經抓取的所有網頁,以得到統一的更新機會,全部的網頁不加區別地按照一樣的頻率被爬蟲重訪。

2)個體的重訪策略:不一樣網頁的改變頻率不一樣,爬蟲根據其更新頻率來決定重訪個體頁面的頻率。即對每個頁面都量身定作一個爬蟲重訪頻率,而且網頁的變化頻率與重訪頻率的比率對任何個體網頁來講都是相等的。

固然兩種方式各有利弊,針對與本課題中電子產品的搜索,因爲網頁更新頻率較慢,且各網頁更新頻率相似,因此可採用策略1.

1.3 分佈式網絡爬蟲

前面所講的內容大多基於單機節點之上,然而單機系統難以知足互聯網上海量網頁的搜索,這促使咱們選擇分佈式構建網頁蒐集系統,由於網頁的蒐集任務基本上可看做是相互獨立的任務,使用分佈式系統,能大大加快網頁的蒐集能力。本節將主要講解基於分佈式網絡爬蟲的大致架構以及設計中出現的主要問題。

在圖1-1中可看到,蒐集器中對應了一個控制器,在分佈式蒐集系統中,將會出現多個蒐集器控制器對,而後再有一個總控制器,以下圖所示:


圖1-4分佈式Web蒐集系統

如圖1-4即爲網頁蒐集系統的整體分佈式結構,圖1-4介紹以下:

1.3.1 抓取進程

抓取進程的工做示意圖以下:


圖1-5 爬取進程示意流程圖

注:一個爬取進程內會有多個爬取線程。

圖1-5解釋以下:

a.    首先爬取線程爬取URL時,先由Robots協議模塊判斷是否在網頁服務器容許爬取的URL內,如果,則轉到b,不然轉到c;
b.    爬取線程將爬取到的網頁遞交給網頁處理模塊,網頁處理模塊會分析網頁內的連接,並將網頁內容組織成必定格式(3.2.1節)等,將組織後的內容壓縮後插入到網頁數據庫中,並向爬取線程返回網頁內的的全部連接內容;
c.    爬取線程將網頁處理模塊的全部連接(若未爬取,則爲空)和當前URL遞交到協調進程;
d.    協調進程向該爬取線程返回下一待爬取URL,回到a。

步驟b中,組織網頁即爲將多個網頁組織在一塊,正如1.2.1節所述,而後將組織後的內容壓縮處理後插入到數據庫中。

1.3.2 協調進程

協調進程的設計是關鍵,其中涉及到爲爬取進程分配URL,處理非本區域URL,管理爬蟲線程等等工做。

協調進程從0開始編號,直到n-1,其中n爲爬蟲主機數,各個協調進程管理本身所屬的URL,即爲如下策略:

URLs = {URL1,URL2, …, URLn},即URLs爲全部URL的集合,定義HOST(URL)爲一個網頁地址的域名部分,一般對應某臺Web服務器,例如:URL = http://www.scie.uestc.edu.cn/main.php?action=viewTeacher,則HOST(URL)= http://www.scie.uestc.edu.cn,所採起的策略是創建一個HOST(URL)到[n]之間的映射,一旦一個HOST(URL)映射到了某一搜集節點,該節點就要負責HOST(URL)下面全部頁面的收集。映射函數可採用散列函數。每一個協調進程同時維護還要維護兩張表,正如3.2.1節所述,visited_table和unvisited_table,協調進程工做的具體僞碼流程以下[2]

for(;;)
begin
a.    等待從其它節點傳來的一個URL,或者它所管轄的抓取進程返回一個URL及相關links。
b.    若獲得其它節點傳來的一個URL
b.1 看URL是否已經出如今visited_table中,若沒有,則將URL放到unvisited_table中;
       c. 若獲得從抓取進程返回的URL,取得超連接links;
              c.1 從unvisited_table中分給給該抓取進程一個新的URL,並將返回的URL放到visited_table中;
              c.2 並對每一個超連接符號串HOST(link)進行模n散列,獲得某個整數I;
              c.3 對每個超連接link及其對應整數i:
                     c. 3.1 若是本節點編號爲i,執行b.1的動做
                     c. 3.2 不然,將link發給節點i
end

上述僞代碼即爲協調進程工做算法,詳細解釋以下:

步驟a中協調進程中,只會處理屬於本節點區域的URL,因此它會等待兩個事件:其它節點傳來屬於本節點的URL和本節點上爬取進程傳來的爬取的URL及相關links:

當此事件是其它節點傳來URL,則首先須要驗證該URL是否已經訪問過(使用hash函數在visited_table中比較,正如1.2.1節所述),若未訪問過,則插入到unvisited_table中供爬取進程爬取;

當此事件是本節點的爬取進程爬取的URL和相關links時(其中的相關links即爲網頁處理模塊已分析出的網頁內容中的連接),則協調進程會給該爬取進程分配下一待爬取URL。而後協調進程會分析相關links,對連接中的URL做散列操做,若散列的結果爲本協調進程的編號時,則執行b.1操做,即判斷該URL是否已經訪問,若已訪問,則丟棄,不然,則插入到unvisited_table中;當散列的結果不是本協調進程時,則發送給相應的協調進程。

1.3.3 調度模塊

調度模塊的工做就是維護系統內全部登記進程的信息,包括它們的IP地址和端口號,當任何一個協調進程的信息有所變化時,該模塊負責將更新的信息轉送給其它協調進程。

調度模塊是網頁蒐集系統可擴展性的關鍵,它會爲各協調進程分配URL,正如上一節中所述。系統擴展性體如今於:當其中一個協調進程模塊因某種緣由而崩掉時,調度模塊會將該協調進程的信息分配到其它協調進程模塊。

1.4 小結

本章內容主要講解了電子產品網頁蒐集系統的組成、關鍵問題和設計細節。最開始引出一個網絡爬蟲的概念,而後敘述網絡爬蟲須要考慮的一系列問題,例如避免URL重複、格式轉換、存儲等等,由於單機系統難以適應海量網頁的抓取,接着文章講解了分佈式網頁蒐集系統的系統架構結束了本章的內容,固然,實際設計系統時,還會在這些內容上根據實際狀況進行取捨。


參考文獻

[1] 潘雪峯, 花貴春, 梁斌. 走進搜索引擎.2011.5. 電子工業出版社. [2]  W.BruceCroft, Donald Metzler, Trevor Strohman等. 2010.2. 搜索引擎: 信息檢索實踐. 北京:機械工業出版社. [3] 李曉明, 閆宏飛, 王繼民等. 2012. 搜索引擎: 原理, 技術與系統. 北京:科學出版社. [4]  https://en.wikipedia.org/wiki/Web_search_engine. [5]  https://en.wikipedia.org/wiki/Hash_function. [6]  https://en.wikipedia.org/wiki/Bloom_filter. [7]  Bloom,Burton H. (1970), "Space/Time Trade-offs in Hash Coding with AllowableErrors", Communications of the ACM 13 (7):422–426, doi:10.1145/362686.362692 [8]  https://en.wikipedia.org/wiki/Naive_Bayes_classifier. [9]  https://en.wikipedia.org/wiki/Support_vector_machine. [10]  CHO, J. AND GARCIA-MOLINA, H.2000a, Estimating frequency of change. ACM Transactions on Internet Technology,Vo1.3, No.3, 2003.8. [11]  https://en.wikipedia.org/wiki/NoSQL [12]  https://en.wikipedia.org/wiki/Rabin_fingerprint 
相關文章
相關標籤/搜索