Nutch教程——準備篇 by 逼格DATA

逼格DATA發表於2015-02-09

實在是看不下去Nutch官方的坑爹教程了,總結一套看完能懂的Nutch教程,持續更新中。


開發環境和基礎:

學習Nutch,必須滿足以下幾個條件,缺一不可:

1)Linux環境,實在是沒辦法就在Windows上裝Linux虛擬機器。

2)熟悉JAVA。

3)有hadoop基礎,能夠編寫hadoop下map reduce程式。

4)能夠看懂Linux Shell。


下面來解釋以下為什麼需要滿足這些條件。Nutch是在hadoop上執行的,windows下跑hadoop有一定的問題。並且Nutch中流程的控制使用的是Linux Shell,在windows上實現也比較麻煩。如果看不懂Linux Shell,就看不懂Nutch的流程。Nutch被切分成幾個流程,每個流程都由Map Reduce完成,如果沒有Map Reduce程式設計的基礎,就看不懂Nutch原始碼。


原始碼閱讀:

千萬不要拿Nutch原始碼作為爬蟲入門的教程。在學習Nutch之前最好先找一個單機爬蟲熟悉爬蟲的流程和基礎。如果連Http請求、網頁資訊抽取這些最基礎的技術細節都搞不清楚,閱讀Nutch原始碼是沒有用的,雖然說Nutch的http請求、網頁解析是通過外掛來完成的,但是我可以告訴你,如果你對Nutch的工作流程不是非常瞭解,是寫不了Nutch外掛的,哪怕是最簡單的外掛,所以不要想通過閱讀Nutch外掛的方法,來學習怎麼傳送http請求這種基礎。更重要的是,在閱讀Nutch原始碼之前,一定要了解爬蟲的流程。Nutch中每個流程的輸入輸出都存放在hadoop檔案中,檔案是SequenceFIle,直接無法正確閱讀檔案的內容,如果想通過觀察SequenceFile來了解爬蟲的流程,是比較困難的。JAVA開源的單機爬蟲有很多種,和Nutch流程最相似的是WebCollector。WebCollector和Nutch一樣,都是將完整廣度遍歷切分成一層一層的爬取(每一層對應樹的一層),有相同的連結儲存、更新機制,採用相同的執行緒池,可以通過閱讀WebCollector的原始碼來作為學習Nutch的基礎。


分散式:

寫Nutch程式碼不需要分散式知識,用Map Reduce框架寫程式碼,會自動完成程式碼的分散式執行。Nutch的所有流程都是用Map Reduce完成的,如果你沒有Map Reduce的基礎,Nutch的程式碼基本就和天書一樣。在學習Nutch前,至少要能夠自己編寫hadoop官方教程中的WordCount的程式碼。

亂碼?索引?:

相信很多用過Nutch的人都有疑問,按照官方教程爬取網站後,網頁存在哪裡了?的確看到產生了中間檔案,但是為什麼是亂碼?這些亂碼是因為給網頁做了索引麼?
如果你有這種疑問,應該去學習一下hadoop了。和上面說的一樣,沒有hadoop基礎看不懂Nutch。Nutch預設會儲存所有的網頁,但是網頁並不是按照網站結構儲存的。在一輪爬取中,所有的網頁都被放到一個叫content的資料夾中,資料夾中有若干個檔案,這種檔案叫SequenceFile,SequenceFile可以認為是儲存JAVA中物件(一個或多個)的檔案,網頁原始碼被封裝在一個Content型別的物件中(Content.java原始碼),Nutch就是將這些Content型別的物件,儲存在SequenceFile中。如果你用文字編輯器檢視SequenceFIle,看到的就是亂碼,而不是因為做索引導致的亂碼。
至於SequenceFile怎麼讀寫,這是hadoop的基礎,想使用Nutch採集的資料,就去學學怎麼讀取SequenceFile吧。

開發工具:

官網下到的Nutch原始碼是用ant進行管理的,官方有個教程用ant命令將專案轉換成eclipse專案,但是我個人非常不建議用eclipse作為開發工具。Intellij和Netbeans可以相容eclipse專案,也可以用來開發Nutch。關於三個IDE的對比這是比較有爭議的問題,這裡不多說。不過這裡最推薦的還是Intellij,後面的教程也都是用Intellij作為示範。

二次開發:

上面說了可以將Nutch原始碼放到Intellij中進行二次開發,但是我們這裡說一下對Nutch二次開發個人的見解。對Nutch的開發主要是開發Nutch外掛,Nutch的外掛的確強大,但是Nutch的外掛是為了搜尋引擎設計的,如果你的業務是做資料採集,修改這些外掛基本沒有意義,有時候還會帶來不必要的麻煩。Nutch常用的外掛有:
1)URL正規化
2)正則過濾器
3)http請求器
4)網頁解析器
5)網頁打分
6)索引
7)其他
這些外掛裡,http請求器和網頁解析器被修改的最多,剩下的外掛基本沒有什麼修改的需求。如果爬蟲被網站封殺,最常用的方法就是修改http請求器,使得http請求可以使用代理池。這裡重點說網頁解析器。一些企業選擇的方案就是在網頁解析模組中,加上網頁抽取的程式碼,使得在解析的同時,將資料插入mysql。
網頁解析外掛有2個作用:
1)抽取網頁中的連結,後面被存放到hdfs中,作為待爬取的連結。
2)抽取網頁中的一些資訊,例如標題、描述,後面被存放到hdfs中,作為索引階段提交給索引伺服器的資料(用作搜尋)。
網頁解析的效率非常地高,而且在Nutch中是一個大量執行緒並行的操作。一秒可以對大量網頁進行資訊抽取、存放到hdfs檔案中。但是如果非要在網頁解析外掛中,將結構化資料提交到mysql,會因為插入速度太快而導致mysql插入操作阻塞。而且網頁抽取的業務經常變化,如果將抽取業務寫到網頁解析外掛中,業務變化,就要重新爬取。
我個人比較喜歡的一種方法,是不修改Nutch的原始碼,只用Nutch作為爬取器。Nutch自動將網頁url和原始碼都根據抓取時間存放在SequenceFile中。寫一套獨立於Nutch的程式,來讀取SequenceFile,做網頁抽取、結構化資料持久化,會使得程式更穩定。

版本:

Nutch的版本主要分為Nutch 1.x和Nutch 2.x,非常不建議使用Nutch 2.x,雖然說Nutch 2.x可以將資料放到HBASE、MYSQL等資料庫中,但是目前Nutch 2.x一直處在開發階段,我們官網上下到的Nutch 2.x (最新的是Nutch 2.3)都需要經過一定的修改才可以正常執行,而且官網並沒有給出相關文件,官網的Nutch 2.x教程非常不負責任,相信以前學過Nutch的都知道,官方的Nutch 2.x教程並不能用,那是因為官網提供的下載是Nutch 2.2.1版本,而官網所謂的Nutch 2.x指的是在社群svn中維護的Nutch 2.3的未完成版。換句話說,Nutch 2.x還屬於在社群中開發的階段,社群還沒有給出正式的文件和教程。

除了文件欠缺、版本不穩定之外,Nutch2.x的持久化也是一個大問題。先說Nutch2.x利用mysql做持久化,這就是一個搞笑的設定。在hadoop上跑程式,用mysql作為輸入輸出,效率大家都懂得。而且選用Nutch作為爬蟲,一般都是要處理幾千萬以上的資料。Mysql存一般多萬網頁已經可以崩潰了。其實我一直覺得官方也不想給出Nutch2.x持久化到mysql這種設定,我覺得官方只是想告訴大家,Nutch2.x使用的gora可以通過配置,將資料持久化到各種資料庫。

很多人衝著Nutch 2.x可以持久化到hbase,而選用Nutch 2.x,當然配成功的很少,最後使用的更少。對於Nutch2.x與hbase,需要了解下面幾點:

1)hbase的宗旨是提供一個無窮大的儲存,hbase中每行資料都有一個唯一的key,在hbase中對資料的查詢最好是在已知key的情況下進行,但是很多使用者的需求,是想通過與sql中select操作類似的方法來查詢資料,這種不可取。

2)Nutch 2.x所謂的儲存資料到hbase,是將一些爬取輔助資訊(歷史爬取歷史)、網頁原始碼和連結分析資訊儲存到hbase中。如果你想用爬蟲完成一邊爬去一邊抽取精資料,然後放入hbase,你需要自己去寫插入hbase的操作,並不能通過Nutch 2.x自帶的功能完成。

3)hbase如果崩潰,修復並不是很容易。很有可能爬了一個月的資料就救不回來了。

根據我的經驗,Nutch 1.x可以為企業提供一個非常穩定的爬蟲。雖然他並沒有使用資料庫來維護資料,但是它的穩定性卻遠遠高於目前的Nutch 2.x版本。Nutch使用檔案來維護所有的爬取資訊(hdfs中的檔案),Nutch 1.x將每個任務的資料都分別新建一個(或者多個)資料夾來管理(預設資料夾名是當前時間),並且對檔案有一定的備份機制,本身就很少出致命錯誤(導致檔案損壞不能用的錯誤)。如果遇到極端情況,導致檔案損壞,可以通過刪除損壞檔案來輕鬆恢復,因為每次任務只會影響到當時新建的資料夾(這裡描述並不是非常準確,後面教程中解釋)。

有一些工程師不能接受這種設定,他們原來是做基於關係型資料庫的系統出生的,對於用檔案儲存資料這種設定不是很能接受。這種習慣要改改了,至少目前,做hadoop這套東西,基於hdfs中檔案去儲存、管理海量資料,還是一個比較穩定的方案。hdfs中有一種檔案叫SequenceFile,這種檔案將java物件儲存到檔案中,也就是說,可以利用檔案儲存結構化資訊,所以不用擔心用檔案儲存不了複雜結構的資料。Nutch 1.x中所有的資料都是用SequenceFIle的形式來儲存的。

最後說個題外話,Nutch 2.x之所以用hbase作為儲存,有一個很重要的原因是,Nutch是為搜尋引擎設計的爬蟲,用hbase可以完成mysql實現不了的連結分析的功能。我們知道網際網路中的連結資訊,用mysql無法實現大量的儲存,入口網站一個頁面就有幾十個外鏈,隨便幾十萬個網頁就可以把mysql弄報廢,而且資料量一大查詢效率你懂得。但是hbase就可以很好地完成這個功能。Nutch 2.x的hbase中,有一個列族叫outlink,這個列族用來儲存每個頁面的所有外鏈資訊,列名是連結的url,列值是連結的錨文字。例如一個網頁http://www.abc.com有2個外鏈,一個指向百度首頁,一個指向新浪首頁。在hbase裡就是:

row_key:"http://www.abc.com:   outlink:http://www.baidu.com:百度一下,你就知道

row_key:"http://www.abc.com:   outlink:http://www.sina.com:新浪首頁

這裡注意一下,http://www.baidu.com和http://www.sina.com並不是值,而是列名。hbase中列族不可以隨便增加,但是列是可以隨意新增的。可想而知,當爬蟲爬取後,hbase的outlink列族中,會有幾百萬個列(有多少不同的連結url,就有多少列)。這樣儲存,我們就可以很快地查詢網際網路中兩個頁面之間的關係。例如我們想查詢http://www.abc.com和http://ww.baidu.com這兩個頁面之間的關係,只需要查詢hbase中,row_key為http://www.abc.com的行中,列族為outlink,列名為http://www.abc.com的單元的值即可。這種查詢操作在搜尋引擎的連結分析中有非常重要的作用。但是如果一個企業只是想對網際網路中的新聞進行爬取、輿情分析,極少會有這種需求。

所以如果企業想使用分散式爬蟲,並且不是為了專門做搜尋引擎,最好使用Nutch 1.x。不要為了使用”高階“的nosql(hbase),而去強行使用Nutch 2.x。

相關文章