轉載地址:http://blog.csdn.net/historyasamirror/article/details/6706174
雖然打着Heritrix的名頭,但本文更多的還是談談增量抓取的基本思想,Heritrix只是正好被用來做爲例子。
如果你不是隨便寫個爬蟲抓着玩,那麼一定會碰到一個問題,就是增量抓取。不管是百度,google這樣的廣泛搜索引擎,還是現在很火的垂直搜索,增量抓取一定都是做爬蟲的最需要考慮的問題。
之所以需要增量抓取的原因,有兩個:
1. 網站總是在不斷的發生着變化。或者添加了新的網頁,或者舊的網頁內容發生了變化;
2. 並沒有機制能夠將網站發生的變化主動的推送給搜索引擎,如果有這種機制,一切都將變得簡單,也就不需要爬蟲去做增量抓取;
增量抓取的目的就在於儘可能快的抓取到變化了的網頁(包括新增的和發生變化的舊的網頁):
之所以需要儘可能的快,是因爲這直接關係到搜索引擎提供的信息的時效性。假設一個網頁發生了變化,而爬蟲一個月之後才重新重新抓取,那麼意味着搜索引擎內關於這個網頁的信息在這一個月之內都是過時的;
之所以是儘可能的快,是因爲爬蟲的增量抓取這種方式永遠都不可能保證一定能夠及時發現變化的網頁。哪怕重複抓取的頻率很快,也不能避免網頁在兩次抓取之間發生了變化。如果希望達到實時性,就只能通過接口調用。比如google爲了實時搜索twitter的信息,購買了twitter的數據,twitter只要產生新的數據就會推送給google;再比如我之前聽過一個“去哪兒”的講座,爲了保證搜索到的機票價格一定是最及時的,在每次搜索的時候,都實時的調用航空公司的接口實時的獲取機票價格,這是一個典型的犧牲服務的響應速度而保證信息時效性的例子(幾年前聽說的,不確定還是這麼做...);
根據前述,構建一個增量抓取的爬蟲主要有兩個要素:
1. 如何能夠儘可能快;
2. 怎樣判斷網頁發生了變化;
先說第一點。如果是抓取特定的網站,那麼可以引入一些先驗知識。比如,網站的索引頁總是能夠關聯上哪些新增加的網頁,一個網站的變化頻率也可以簡單的估計。通過引入這些知識,爬蟲可以很容易的很快的找到那些可能發生變化的網頁。而對於像百度這樣的搜索引擎,因爲需要抓取所有的網頁,它不太可能去一一分辨每個網站的索引頁,這種情況下,就必須有動態學習和調節網站抓取頻率的機制,對於那些變化快的網站/網頁,重複抓取的頻率就應該高,而那些幾乎不變化的網頁,重複抓取的間隔就可以很長。
關於第二點,看上去似乎很簡單,只需要字符串比較一下新的網頁和上次抓取的版本是否發生了變化。但是在很多情況下,網頁的字符可能發生了微小的變化,但並不意味着網頁的實質內容發生了變化。舉例來說,網頁上有個地方寫着系統的當前時間,這意味着每次查看該網頁時間都會變,但是,網頁的真正內容可能從未發生過變化。如何過濾這些信息而能夠判斷網頁內容的真實變化並不是一件容易的事。
說了這麼多幹巴巴的東西,還是看看Heritrix怎麼做的吧。
(以下的內容需要對Heritrix的架構和模塊有一個基本的瞭解)
爲了實現Heritrix的增量抓取功能,需要在Processing Chains中添加幾個新的組件,如下圖:
在Extractor Processing Chain的最前端,加入一個新的模塊:HttpContentDigest,這個模塊會對有Fetch Processing Chain抓取下來的網頁產生一個摘要,這個摘要就是爲了判斷網頁是否發生了變化,這個摘要的產生必須要考慮到我們之前提到過的網頁的細節發生變化,但是內容無變化的這種情況;
HttpContentDigest之後會有一個ChangeEvaluator的模塊,這個模塊根據HttpContentDigest產生的新的網頁摘要以及上一次抓取生成的舊的摘要的對比,判斷網頁是否發生了變化;
在Post Processing Chain中會加入一個WaitEvaluator,這個模塊的作用,是根據ChangeEvaluator的結果動態的調節該網頁的抓取頻率,並給出該網頁下一次的抓取時間。還是舉例說,比如這個url之前的抓取頻率是1天,意味着1天重複抓取一次。如果ChangeEvaluator判斷本次抓取網頁的內容發生了變化,那麼WaitEvaluator會將該url的抓取頻率設置爲 1天 / 2 = 12小時,意味着它的抓取頻率需要更快;如果網頁內容沒有發生變化,那麼新的抓取間隔會被設置爲 1天 * 2 = 2天。
其本質就是根據網頁抓取後內容是否變化來動態調節抓取頻率。
此外,Heritrix的Froniter也需要改成AdaptiveRevisitFrontier。Heritrix默認的Froniter內部是一個FIFO的隊列,而AdaptiveRevisitFrontier內部則是一個優先級隊列。它根據WaitEvaluator設定的wait time(也就是抓取間隔)來排列url,判斷哪個url應該被調度。
(注:AdaptiveRevisitFrontier是一個實驗性質的Froniter: EXPERIMENTAL Frontier that will repeatedly visit all encountered URIs. Wait time between visits is configurable and is determined by seperate Processor(s). See WaitEvaluators See documentation for ARFrontier limitations.)