本文首先介紹 Nutch 的背景知識,包括 Nutch 架構,爬蟲和搜索器。然後以開發一個基於 Nutch 的實際應用爲例向讀者展示如何使用 Nutch 開發自己的搜索引擎。在該示例中,首先帶領讀者開發一個作爲 Nutch 爬蟲抓取的目標網站,目標網站將被部署在域名爲 myNutch.com 的服務器上。然後示例說明 Nutch 爬蟲如何抓取目標網站內容,產生片斷和索引,並將結果存放在集羣的2個節點上。最後使用 Nutch 檢索器提供的 API 開發應用,爲用戶提供搜索接口。
Nutch 是一個基於 Java 實現的開源搜索引擎,其內部使用了高性能全文索引引擎工具 Lucene。從 nutch0.8.0開始,Nutch 完全構建在 Hadoop 分佈式計算平臺之上。Hadoop 除了是一個分佈式文件系統外,還實現了 Google 的 GFS 和 MapReduce 算法。因此基於 Hadoop 的 Nutch 搜索引擎可以部署在由成千上萬計算機組成的大型集羣上。由於商業搜索引擎允許競價排名,這樣導致索引結果並不完全是和站點內容相關的,而 Nutch 搜索結果能夠給出一個公平的排序結果,這使得 Nutch 在垂直搜索、檔案互聯網搜索等領域得到了廣泛應用。
- Rational Application Developer v6.0
- Websphere Application Server v6.0
- Nutch 0.8.1
- SSH Service Package
- 主節點RHAS3.0
- 從節點Debian GNU/Linux 3.1
Nutch 搜索引擎是一個基於 Java 的開放源代碼的搜索引擎。Nutch 搜索引擎處理流程包括抓取流程和搜索流程,如圖 1 所示。相應地 Nutch 也分爲2部分,抓取器和搜索器。在抓取流程中,抓取器也叫蜘蛛或者機器人,以廣度優先搜索(BFS)的方式從企業內部網或者互聯網抓取網頁。這個過程涉及 到對 CrawlDB 和 LinkDB 數據庫的操作。然後 Nutch 解析器開始解析諸如 HTML、XML、RSS、PDF等不同格式的文檔。最後 Nutch 索引器針對解析結果建立索引並存儲到 indexDB 和 SegmentsDB 數據庫中,以供搜索器搜索使用。
在搜索流程中,搜索應用使用輸入關鍵詞調用 Nutch 搜索接口(Nutch Query Interface)。應用可通過網頁上的輸入框輸入相應關鍵詞。搜索接口解析搜索請求爲 Lucene 全文檢索引擎可以識別的格式。Nutch 索引器將會調用 Lucene 引擎來響應請求在 indexDB 上展開搜索。最後搜索接口收集從索引器返回的URL、標題、錨和從 SegmentsDB 返回的內容。所有上述內容將被提供給排序算法進行排序。排序完成後,搜索接口將返回命中的搜索結果。由於構建在 Hadoop 分佈式文件系統之上, Nutch 對CrawlDB, LinkDB, SegmentsDB 和 IndexDB 數據庫的操作都是通過調用 M/R(map/reduce) 函數完成的。這使得 Nutch 具有了集羣擴展能力。
現在將開發一個供 Nutch 爬蟲抓取的目標網站應用。這個應用使用 RAD v6.0(Rational Application Developer)作爲集成開發工具開發。應用開發完成後,將被部署在 WAS v6.0(Websphere Application Server)服務器上,本樣例中服務器的域名設置是 myNutch.com。讀者可以按照下面的步驟來開發該目標網站應用。
- 創建一個動態 Web 項目。打開 RAD,選擇 File > New > Project,然後在嚮導裏選擇動態 Web 項目,如圖 2 所示。
圖 2 創建一個動態 Web 項目 - 設計網頁。在項目裏面,選擇 File > New > HTML/XHTML,創建 index.html, one.html,two.html 和 three.html 一共4個文件。 項目的最終結構組成如圖 3 所示。
圖 3 項目的最終結構組成 - 在 WAS v6.0 中運行項目。 打開 RAD, 選擇 project > Run > Run on Server, 部署並在服務器上運行。如圖 4 所示。
圖 4 在服務器上運行 - 點擊完成按鈕。啓動瀏覽器,在地址欄中輸入 http://myNutch.com/targetWebApp。如圖 5 所示。
圖 5 在瀏覽器中訪問
在抓取網站之前,需要定義搜索引擎。在本樣例中Nutch被配置爲集羣方式。集羣包括主節點(地址9.181.87.172,操作系統 RHAS3.0)和從節點(地址 9.181.87.176,操作系統 Debian)。如前文介紹,Nutch 的集羣能力主要利用了 Hadoop 的分佈式計算環境。下面介紹如何定義 Nutch 搜索引擎。
- 安裝 Nutch。首先下載 Nutch 安裝包。本示例採用 Nutch0.8.1。解壓下載到的 Nutch 0.8.1包到主節點某一工作目錄下。本文中的工作目錄使用 /workspace 。確認主從節點上都已安裝 SSH service package和 JDK1.4 或 JDK 1.5
- Nutch 設置。在 Nutch 的工作目錄下,用文本編輯器打開 conf 目錄下的文件 Nutch-site.xml,輸入
http.agent.name,http.agent.description,http.agent.url 和 http.agent.email
屬性集。注意 http.agent.ur 屬性需要填寫部署目標網站的域名地址 myNutch.com。清單 1 列出了修改完畢後的
Nutch-site.xml。
清單 1 Nutch-site.xml<property>
<name>http.agent.name</name>
<value>Nutch-hadoop</value>
<description>HTTP 'User-Agent' request header. MUST NOT be empty -
please set this to a single word uniquely related to your organization.
</description>
</property>
<property>
<name>http.agent.description</name>
<value>bydenver</value>
<description>Further description of our bot- this text is used in
the User-Agent header. It appears in parenthesis after the agent name.
</description>
</property>
<property>
<name>http.agent.url</name>
<value>myNutch.com</value>
<description>A URL to advertise in the User-Agent header. This will
appear in parenthesis after the agent name. Custom dictates that this
should be a URL of a page explaining the purpose and behavior of this
crawler.
</description>
</property>
<property>
<name>http.agent.email</name>
<value>[email protected]</value>
<description>An email address to advertise in the HTTP 'From' request
header and User-Agent header. A good practice is to mangle this
address (e.g. 'info at example dot com') to avoid spamming.
</description>
</property> - Hadoop 主節點設置。 用文本編輯器打開 conf 目錄下的文件 hadoop-site.xml,插入清單 2
所列出的屬性集。需要注意的是屬性 fs.default.name 和 mapred.job.tracker
設置爲主節點的IP地址(在本例中爲9.181.87.172)。
清單 2 hadoop-site.xml文件<property>
<name>fs.default.name</name>
<value>9.181.87.172:9000</value>
<description>
The name of the default file system. </description>
</property>
<property>
<name>mapred.job.tracker</name>
<value>9.181.87.172:9001</value>
<description>
The host and port that the MapReduce job tracker runs at.
</description>
</property>
<property>
<name>mapred.map.tasks</name>
<value>2</value>
<description>
define mapred.map tasks to be number of slave hosts
</description>
</property>
<property>
<name>mapred.reduce.tasks</name>
<value>2</value>
<description>
define mapred.reduce tasks to be number of slave hosts
</description>
</property>
<property>
<name>dfs.name.dir</name>
<value>/workspace/filesystem/name</value>
</property>
<property>
<name>dfs.data.dir</name>
<value>/workspace/filesystem/data</value>
</property>
<property>
<name>mapred.system.dir</name>
<value>/workspace/filesystem/mapreduce/system</value>
</property>
<property>
<name>mapred.local.dir</name>
<value>/workspace/filesystem/mapreduce/local</value>
</property>
<property>
<name>dfs.replication</name>
<value>2</value>
</property> - Hadoop 從節點設置。使用文本編輯器打開 conf 目錄下的 slaves 文件,輸入從節點的 IP 地址。如清單 3 所示。
清單 3 slaves 文件9.181.87.176
- 抓取器設置。首先在 Nutch 工作目錄下創建目錄 urls,再新建文件 urllist.txt。編輯
urllist.txt文件,輸入 http://myNutch.com/targetWebApp。清單 4 列出了所使用的命令。最後需要編輯
conf 目錄下的 crawl-urlfilter.txt 文件,輸入
+^http://([a-z0-9]*/.)*myNutch.com/,如清單 5 所示。
清單 4 創建 urllist 文件cd /workspace/Nutch-0.8.1
mkdir urls
echo http://myNutch.com/targetWebApp > urls/urllist.txt
conf/crawl-urlfilter.txt
清單 5 編輯crawl-urlfilter.txt 文件+^http://([a-z0-9]*/.)*myNutch.com/
在使用 Nutch 抓取之前,首先需要啓動 Hadoop 服務。清單 6 列出了啓動 Hadoop 服務所採用的命令。隨後使用清單 7 中的命令從 myNutch.com 抓取網頁並解析,其中參數 “depth 3” 表示從網頁根路徑算起的鏈接深度;參數 “topN 10” 表示抓取器在每層需要獲取的最大頁面數目。開始抓取後,抓取器將在當前目錄下創建新目錄 crawl 作爲工作目錄。
bin/hadoop dfs -put urls urls |
bin/Nutch crawl urls -dir ./crawl -depth 3 -topN 10 |
對目標網站 targetWebApp 完成抓取後, 在 crawl 工作目錄下產生了五個子目錄: crawldb,linkdb,segments,indexes 和 index (見圖 6)。數據庫 crawldb 中包含頁面的數目等;linkdb 包含頁面在數據庫中的鏈接,這是抓取器真正抓取網站時由頁面的鏈接數目決定;Segments 數據庫按照時間戳分爲三個片斷,每個片斷的產生都經歷了 generate/fetch/update 三個過程;Indexes 數據庫包含了在 generate/fetch/update 過程中產生的 Lucene 索引;Index 數據庫包含了經合併處理後的 Lucene 索引。
讀者也可以使用工具 Luke 去查看 Lucene 索引。 藉助 Luke,可以查看索引內容以及對索引查詢。圖 7 列出了 index 目錄下的合併後的索引。
完成抓取後,現在將開發一個基於 Nutch 搜索 API 的應用 NutchApp,提供給用戶作爲搜索的接口。NutchApp 使用 Java 語言編寫,其實現首先創建 NutchConfiguration 對象,然後創建 NutchBean。這個 NutchBean 實例將用來處理用戶的搜索請求;根據請求參數,創建 query 對象,NutchBean 通過調用 search 方法來處理此 query 對象的請求。最終搜索結果以 Hits 集合。NutchApp 遍歷此 Hits 集合並打印結果到標準輸出。清單 8 列出了 NutchApp 的示例代碼。
package org.myNutch; |
接下來我們來運行 NutchApp。首先編譯 NutchApp.java 並打包。打包後的文件名爲 NutchApp.jar。隨後在 Nutch 命令下執行。見清單 9。
Javac -cp "Nutch-0.8.1.jar;hadoop-0.4.0-patched.jar" src/org/myNutch/NutchApp.java -d lib |
下面我們可以驗證我們開發的 Nutch 搜索引擎的使用效果。在搜索頁面搜索關鍵字輸入“Nutch”,NutchApp 返回的搜索結果如清單 10 所示。其中包括概要和詳細內容。
Total hits: 3 |
通過本文的介紹,現在你已經知道如何使用 Nutch 開發集羣式的搜索引擎,並使用此搜索引擎對目標網站進行抓取和分析結果,以及如何提供搜索接口來響應用戶的搜索請求。事實上,搭建基於 Nutch 的搜索引擎是一個具有很大挑戰性的工作,因爲 Nutch 本身還在不斷的發展之中,另外目標網站的結構複雜度也不盡相同。所以,針對互聯網站點文檔格式日益複雜的需求,接下來你還需要花一些精力關注 Nutch 高級特性的進展。
學習
- 在 Nutch 官方網站
閱讀更多有關 Nutch 的在線文檔
- 在 Lucene 官方網站
閱讀更多有關 Lucene 的在線文檔
- 在 Hadoop 官方網站
閱讀更多有關 Hadoop 的在線文檔
獲得產品和技術
- 下載IBM JDK
- 下載RAD 試用版
- 下載Websphere 試用版
|
王飛鵬是 IBM 中國軟件開發中心的軟件工程師 |
李立是 IBM 中國研究院的研究員 |
王美華是 IBM 中國軟件開發中心的軟件工程師 |