1. 程式人生 > >使用nutch搭建類似百度/谷歌的搜尋引擎

使用nutch搭建類似百度/谷歌的搜尋引擎

Nutch是基於Lucene實現的搜尋引擎。包括全文搜尋和Web爬蟲。Lucene為Nutch提供了文字索引和搜尋的API。

1.有資料來源,需要為這些資料提供一個搜尋頁面。最好的方式是直接從資料庫中取出資料並用Lucene API 建立索引,因為你不需要從別的網站抓取資料。
2.沒有本地資料來源,或者資料來源非常分散的情況下,就是需要抓別人的網站,則使用Nutch。

1.安裝

1.安裝tomcat

[root@localhost ~]# wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.1/bin/apache-tomcat-9.0.1.tar.gz
[root@localhost ~]# tar xvzf apache-tomcat-9.0.1.tar.gz -C /usr/local/ [root@localhost ~]# cd /usr/local/ [root@localhost local]# mv apache-tomcat-9.0.1/ tomcat [root@localhost local]# /usr/local/tomcat/bin/startup.sh

2.部署nutch
這裡nutch用1.2版本,雖然現在已經很高版本了,但是1.2以上已經沒有war包,沒法做類似百度這種頁面的搜尋了,而是nutch轉而給solr提供搜尋支援。

[root@localhost
~]# wget http://archive.apache.org/dist/nutch/apache-nutch-1.2-bin.tar.gz [root@localhost ~]# tar xvf apache-nutch-1.2-bin.tar.gz -C /usr/local/ [root@localhost ~]# cd /usr/local/nutch-1.2/ [root@localhost local]# mv nutch-1.2/ nutch [root@localhost local]# cd nutch/ [root@localhost nutch]# cp nutch-1.2.war /usr/local/tomcat/webapps/nutch.war

apache下,當瀏覽器訪問 http://localhost:8080/nutch 時nutch的war包會被自動解壓部署。可以看到我們的搜尋頁面

2.爬取資料

nutch目錄下,新建檔案url.txt,把我們要抓的網站填入,內容

https://www.hicool.top/

有個過濾規則,我們上一步填入的網站,需要經過這個規則過濾才可抓取,否則不能。修改過濾規則,檢視conf/craw-urlfilter.txt檔案

# accept hosts in MY.DOMAIN.NAME
+^http://([a-z0-9]*\.)*MY.DOMAIN.NAME/

這其實是一個正則表示式,把加號那一行,改為僅僅允許自己網站通過

+^http://([a-z0-9]*\.)*hicool.top/

這樣可以只把自己的網站抓下來了。修改conf/nutch-site.xml檔案,在configuration標籤內增加如下索引目錄屬性,指定檢索器讀取資料的路徑。另外增加一個http.agent.name和一個http.robots.agents節點,否則不能抓取。因為nutch遵守了 robots協議,在爬行人家網站的時候,把自己的資訊提交給被爬行的網站以供識別。

<property>
    <name>http.agent.name</name>
    <value>hicool.top</value>
    <description>Hello,welcom to visit www.hicool.top</description>
</property>
<property>
    <name>http.robots.agents</name>
    <value>hicool.top,*</value>
</property>
<property>
    <name>searcher.dir</name>
    <value>/usr/local/nutch/crawl</value>
    <description></description>
</property>

searcher.dir是指定搜尋結果存放路徑。http.agent.name的value隨便填一個,而http.robots.agents的value必須填你的的http.agent.name的值,否則報錯”Your ‘http.agent.name’ value should be listed first in ‘http.robots.agents’ property”。

注意:預設不開啟對https網站抓取的支援,如果要開啟,新增如下內容到nutch-site.xml

<property>
  <name>plugin.includes</name>
  <value>protocol-httpclient|urlfilter-regex|parse-(html|tika)|index-(basic|anchor)|indexer-solr|scoring-opic|urlnormalizer-(pass|regex|basic)|parse-jsoup</value>
</property>

這實際是使用了protocol-httpclient外掛下載https網頁,至於別的外掛都是一些過濾解析網頁的。添加了外掛之後,就可以爬https的網站了。目前已有的協議及支撐外掛如下:

http:
    protocol-http
    protocol-httpclient
https:
    protocol-httpclient
ftp:
    protocol-ftp
file:
    protocol-file

Nutch 的爬蟲有兩種方式
• 爬行企業內部網(Intranet crawling)。針對少數網站進行,用 crawl 命令。
• 爬行整個網際網路。 使用低層的 inject, generate, fetch 和 updatedb 命令,具有更強的可控制性。

我們使用crawl命令,抓資料

[[email protected] nutch]# bin/nutch crawl url.txt -dir crawl -depth 10 -topN 100
crawl started in: crawl
rootUrlDir = url.txt
threads = 10
......
......
......
IndexMerger: merging indexes to: crawl/index
Adding file:/usr/local/nutch/crawl/indexes/part-00000
IndexMerger: finished at 2017-10-19 19:59:50, elapsed: 00:00:01
crawl finished: crawl

上面的過程太長,我略過了很多。引數含義說明如下:
-dir 指定存放爬行結果的目錄,本次抓取結果資料存放到sports目錄中;
-depth 表明需要抓取的頁面深度,本次抓取深度為10層;
-topN 表明只抓取前N個url,本次抓取為取每一層的前100個頁面;
-threads 指定Crawl採取下載的執行緒數,我用這個一直抓不到資料,就把它去掉了。

根據下載過程可以看出nutch爬取網頁並建立索引庫的過程如下:
1)插入器(Injector)向網頁資料庫新增起始根URL;
2)按照要求抓取的層數,用生成器(Generator)生成待下載任務;
3)呼叫獲取器(Fetcher),按照指定執行緒數實際下載相應頁面;
4)呼叫頁面分析器(ParseSegment),分析下載內容;
5)呼叫網頁資料庫管理工具(CrawlDb),把二級連結新增到庫中等待下載;
6)呼叫連結分析工具(LinkDb),建立反向連結;
7)呼叫索引器(Indexer),利用網頁資料庫、連結資料庫和具體下載的頁面內容,建立當前資料索引;
8)呼叫重複資料刪除器(DeleteDuplicates),刪除重複資料;
9)呼叫索引合併器(IndexMerger),把資料合併到歷史索引庫中。

本地測試下搜尋結果,搜關鍵字“1”

[[email protected] nutch]# bin/nutch org.apache.nutch.searcher.NutchBean 1
Total hits: 193
 0 20171019203949/https://www.hicool.top/
 ... Liberalman 的主頁 ...
 ......
 ......

搜到了193條資訊。剩下的我都省略顯示了。

使用Readdb工具摘要描述

[root@localhost nutch]# bin/nutch readdb crawl/crawldb/ -stats
CrawlDb statistics start: crawl/crawldb/
Statistics for CrawlDb: crawl/crawldb/
TOTAL urls:     296
retry 0:        286
retry 1:        10
min score:      0.0
avg score:      0.009496622
max score:      1.11
status 1 (db_unfetched):        18
status 2 (db_fetched):  275
status 4 (db_redir_temp):       3
CrawlDb statistics: done

爬到了296個頁面。

3.在web頁面展示搜尋結果

修改/usr/local/tomcat/webapps/nutch/WEB-INF/classes/nutch-site.xml

<property>
    <name>http.agent.name</name>
    <value>hicool.top</value>
    <description>Hello,welcom to visit www.hicool.top</description>
</property>
<property>
    <name>http.robots.agents</name>
    <value>hicool.top,*</value>
</property>
<property>
    <name>searcher.dir</name>
    <value>/usr/local/nutch/crawl</value>
    <description></description>
</property>

把我們上一步抓取資料的存放路徑配置到tomcat下,重啟tomcat,就可以在瀏覽器中搜索了。

4.篩選連結

有些連結我們需要抓取,有些我們則需要排除掉。怎樣才能有一個篩選機制,過濾掉冗餘的連結呢?

編輯conf/regex-urlfilter.txt

# skip file: ftp: and mailto: urls
#過濾掉file:ftp等不是html協議的連結
-^(file|ftp|mailto):

# skip image and other suffixes we can't yet parse
#過濾掉圖片等格式的連結
-\.(gif|GIF|jpg|JPG|png|PNG|ico|ICO|css|sit|eps|wmf|zip|ppt|mpg|xls|gz|rpm|tgz|mov|MOV|exe|jpeg|JPEG|bmp|BMP)$

# skip URLs containing certain characters as probable queries, etc.
-[?*[email protected]=] 過濾掉汗特殊字元的連結,因為要爬取更多的連結,比如含?=的連結

# skip URLs with slash-delimited segment that repeats 3+ times, to break loops
#過濾掉一些特殊格式的連結
-.*(/[^/]+)/[^/]+\1/[^/]+\1/

# accept anything else
#接受所有的連結,這裡可以修改為只接受自己規定型別的連結
+.
# accept anything else
+^https:\/\/www\.hicool\.top\/article\/.*$

如果有哪些路徑我想排除掉,不抓取

-^https:\/\/www\.hicool\.top\/category/.*$
+^https:\/\/www\.hicool\.top\/article\/.*$

這樣/category/頁面下的都排除了。這些正則表示式列表,只要有一個滿足條件filter()方法就返回結果。

抓取動態內容

我們平常訪問網站的時候,往往有”?”以及後面帶引數,這種動態的內容預設也不抓取,需要配置。

在conf下面的2個檔案:regex-urlfilter.txt,crawl-urlfilter.txt

# skip URLs containing certain characters as probable queries, etc.
-[?*[email protected]=] (-改+)

這段意思是跳過在連線中存在? * ! @ = 的頁面,因為預設是跳過所以,在動態頁中存在?一般按照預設的是不能抓取到的。可以在上面2個檔案中都註釋掉:

# -[?*[email protected]=]

另外增加允許的一行

# accept URLs containing certain characters as probable queries, etc.
+[?=&]

意思是抓取時候允許抓取連線中帶 ? = & 這三個符號的連線
注意:兩個檔案都需要修改,因為NUTCH載入規則的順序是crawl-urlfilter.txt-> regex-urlfilter.txt

5.按詞劃分和中文分詞

看看上文最後的效果,你會發現,搜尋是按單個字來區分的,你輸入一句話,每個字都被單獨搜了一遍,導致不想關的資訊太冗餘。原來,nutch預設對中文按字劃分,而不是按詞劃分。
so,我們要達到按詞劃分以減少冗餘的目的,則:
1.修改原始碼。直接對Nutch分詞處理類進行修改,呼叫已寫好的一些分片語件進行分詞。
2.使用分詞外掛。按照Nutch的外掛編寫規則重新編寫或者新增中文分詞外掛。

這裡我使用修改原始碼方式,得下載原始碼重新編譯了。關於 IKAnalyzer3.2.8.jar 這個包,我是在網上搜到下載的。可以看這篇 https://github.com/wks/ik-analyzer 安裝此包。

[root@localhost ~]# wget http://archive.apache.org/dist/nutch/apache-nutch-1.2-src.tar.gz
[root@localhost ~]# tar xvf apache-nutch-1.2-src.tar.gz -C /usr/local/
[root@localhost ~]# cd /usr/local/
[root@localhost local]# mv apache-nutch-1.2/ nutch
[root@localhost local]# cd nutch
[root@localhost nutch]# mv ~/IKAnalyzer3.2.8.jar lib/

編輯原始碼生成檔案 src/java/org/apache/nutch/analysis/NutchAnalysis.jj

130   // chinese, japanese and korean characters
131 | <SIGRAM: <CJK> >

這是按字劃分,改為 | <SIGRAM: (<CJK>)+ >,後面那個”+”號是多次,就組成詞了。

Lucene中使用JavaCC這個Java語言分析器按照規則自動生成的原始碼。確保安裝了該工具。

[root@localhost nutch]# cd src/java/org/apache/nutch/analysis/
[root@localhost analysis]# javacc NutchAnalysis.jj

當前路徑新生成的原始碼會覆蓋掉舊的

修改NutchAnalysis.java

 49   /** Construct a query parser for the text in a reader. */
 50   public static Query parseQuery(String queryString, Configuration conf) throws IOException,ParseException {
 51     return parseQuery(queryString, null, conf);
 52   }
 53 
 54   /** Construct a query parser for the text in a reader. */
 55   public static Query parseQuery(String queryString, Analyzer analyzer, Configuration conf)
 56     throws IOException,ParseException {
 57     NutchAnalysis parser = new NutchAnalysis(
 58           queryString, (analyzer != null) ? analyzer : new NutchDocumentAnalyzer(conf));
 59     parser.queryString = queryString;
 60     parser.queryFilters = new QueryFilters(conf);
 61     return parser.parse(conf);
 62   }

這份程式碼原來是沒有ParseException這個異常處理的,給它IOException的後面加上”,ParseException”,這是我修改過後的。

修改NutchDocumentAnalyzer.java

103   /** Returns a new token stream for text from the named field. */
104   public TokenStream tokenStream(String fieldName, Reader reader) {
105     /*Analyzer analyzer;
106     if ("anchor".equals(fieldName))
107       analyzer = ANCHOR_ANALYZER;
108     else
109       analyzer = CONTENT_ANALYZER;*/
110     Analyzer analyzer = new org.wltea.analyzer.lucene.IKAnalyzer();
111 
112     return analyzer.tokenStream(fieldName, reader);
113   }

我把原來的程式碼註釋了return之前哪一行是新加的。

回到根目錄,修改build.xml,在 <target name="war" depends="jar,compile,generate-docs"></target><lib></lib>之間加入IKAnalyzer3.2.8.jar,使得編譯可以依賴上。

200         <include name="log4j-*.jar"/>
201         <include name="IKAnalyzer3.2.8.jar"/>
202       </lib>

開始編譯

[root@localhost nutch]# ant

編譯成功,產生一個build目錄

[root@localhost nutch]# cp build/nutch-1.2.job ./

再生產war包

[root@localhost nutch]# ant war
[root@localhost nutch]# cp build/nutch-1.2.jar ./
[root@localhost nutch]# cp build/nutch-1.2.war ./

我們的編譯就大功告成了。剩下的就是重複跟上文部署一個搜尋引擎的步驟,過程略。有一點需要說明,新的搜尋介面,輸入關鍵詞進行搜尋,這時會出現空白頁。還需要修改 /usr/local/tomcat/webapps/nutch-1.2/WEB-INF/classes/nutch-site.xml 檔案,新增載入外掛的屬性:

<property>
  <name>plugin.includes</name>
  <value>protocol-http|urlfilter-regex|parse-(text|html|js)|analysis-(zh)|index-basic|query-(basic|site|url)|summary-lucene|scoring-opic|urlnormalizer-(pass|regex|basic)</value>
</property>

這裡使用protocol-http而不是protocol-httpclient,需要注意。重啟後的分詞效果

可以看到已經以“設計模式”、“設計”、“模式”這些詞看分關鍵詞搜尋了,OK,成功!

問題

每次重新爬後,要重啟tomcat才能順利訪問

1. Stopping at depth=0 - no more URLs to fetch

特麼的,網上看一堆類似這麼寫的

bin/nutch crawl url.txt -dir crawl -depth 10 -topN 100 -treads 10

我照抄,結果一直報錯Stopping at depth=0 - no more URLs to fetch.害得我搜便各種各樣的辦法,改來改去,都無濟於事,過濾那個地方的正則表示式我都到別的地方去驗證了,沒問題。0.9和1.2版本換了n次,配置了一堆東西,最後自己發現, -treads 10 這個引數有大問題,帶上它怎麼都失敗,去掉立刻OK了

2. 中文亂碼問題

配置tomcat的conf資料夾下的server.xml
修改如下

    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="UTF-8" useBodyEncodingForURI="true"/>

找到這一段,新增URIEncoding="UTF-8" useBodyEncodingForURI="true"
重啟一下Tomcat

參考

相關推薦

使用nutch搭建類似/搜尋引擎

Nutch是基於Lucene實現的搜尋引擎。包括全文搜尋和Web爬蟲。Lucene為Nutch提供了文字索引和搜尋的API。 1.有資料來源,需要為這些資料提供一個搜尋頁面。最好的方式是直接從資料庫中取出資料並用Lucene API 建立索引,因為你不需要從別

蘋果們的殊途同歸:平臺化發展的必然與可能

開發套件 圖片 原因 傳統 單單 window 數據 iphone 開發平臺 一年一度的百度AI開發者大會,是下半年最值得期待的科技盛會之一。作為AI企業的龍頭,百度在開發者方面所展示出的動向,在世界範圍內都牽動著產業的神經。在這次百度AI開發者大會上,出現了一種非常有趣的

JQUERY仿智慧提示

   若使用jquery智慧提示,則主要使用Ajax動態呼叫後臺。   仿百度谷歌智慧提示,說實話,本篇部落格仿的不太縝密,有待繼續完善。   仿百度谷歌智慧提示,思路主要如下:  

Twitter,這麼多短連結服務(Short Url)到底哪家強?

一、短連結是什麼 短連結,通俗來說,就是將長的URL網址,通過程式計算等方式,轉換為簡短的網址字串。 它的原理也非常簡單,就是採用 Domain Redirect(域名重定向) ,將一個域名自動跳轉到另一個域名。 根據wikipedia描述,短連結的方案最

離線地圖解決方案(離線地圖下載)

離線地圖解決方案,除了買地圖資料,使用專業的ArcGIS來做外,也可以使用GMap.Net來做。 使用了GMap一年了,也有了一些積累,開發了一個可以下載ArcGIS、百度、谷歌、高德、騰訊SOSO、天地圖、Here等地圖的地圖下載器。 百度和google地圖載入顯示如下: 百度普通地圖: 百

都作惡,但到底哪家技術更厲害?你會選擇用哪個?

策劃編輯 | Vincent 作者 | Vincent 編輯 | Natalie AI 前線導讀: 前幾日,人民日報在推特和 Facebook 上釋出歡迎谷歌迴歸的訊息,並強調前提是要遵守中國的法律。耐人尋味的是,這兩個平臺上的訊息沒多久就全部刪除。

  收錄規則 優化技巧 SEO …

網站被百度拔毛,這是很正常的事情。現在踏踏實實做網站不容易,希望這篇文章對大家有所幫助! 鳥站前幾天被百度降權。我很鬱悶,我的站主要的流量都是從百度來的。這對我來說無疑是個大轉變,日3000IP一下變成日800IP 心裡不是滋味。今天我的站又恢復了青春。現在我總結一下自己針對百度降權的一點經驗。 首先收錄被百

Hexo個人部落格站點被收錄

精心寫一篇博文但是沒人看怎麼辦呢?百度搜不到,谷歌搜不到?別慌,還需要將你的網站提交到百度和谷歌。 在開始之前,你可以按照以下格式在百度和谷歌搜尋下你的網站: 注意:提交到谷歌需要科學上網。 提交百度搜索引擎 ps:可能需要個人資訊認證,

搜尋引擎介面

百度搜索介面: http://www.baidu.com/s 例:<form action="http://www.baidu.com/s"  method="get" target="_bl

海量資料搜尋---demo展示搜尋引擎的實現

在我們平常的生活工作中,百度、谷歌這些搜尋網站已經成為了我們受教解惑的學校,俗話說得好,“有問題找度娘”。那麼百度是如何在海量資料中找到自己需要的資料呢?為什麼它搜尋的速度如此之快?我們都知道是因為百度的搜尋引擎,那麼搜尋引擎到底是個什麼東西呢?可能有的程式設計師會想到es,但是es並不能代表搜尋引擎,它只是

Elasticsearch實現類似搜尋引擎搜尋功能(下拉自動補全)

{ "refresh_interval":"3s", "number_of_replicas":1, "number_of_shards":5, "analysis":{ "filter":{ "autocomplete_filter":{ "type":"

網站的SEO優化(提高搜尋引擎收錄,類似

一、簡介 搜尋引擎優化(SEO),指為了提升網頁在搜尋引擎自然搜尋結果中(非商業性推廣結果)的收錄數量以及排序位置而做的優化行為 二、前期準備 1. 域名 · 域名儘量簡短,用戶記憶成本低 · 域名可以與網站主題或網站名稱相呼應,讓人看到域名就能聯想到網站內容 · 域名字

類似首頁搜索靜態圖

link org nav top vlog arch text art ack 1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4

java web通過openoffice實現文件網頁預覽(類似文庫)

  最近研究了一下在網頁上預覽文件(包括office文件和txt、pdf),發現用openoffice+FlexPlayer實現比較理想,就參考了https://blog.csdn.net/ITBigGod/article/details/80300177#commentBox這個部落格自己研究了一下。原始碼

google瀏覽器搜尋引擎怎麼設定單擊在新標籤頁開啟頁面

總述: 因為在平時用谷歌搜東西的時候想開啟一個頁面都要右鍵在新標籤頁開啟頁面,忽然找到一種方式可以直接單擊然後在新標籤頁開啟頁面。 方法: 1.首先得有一個google賬戶。我沒試過,可能沒賬戶也可以吧 2.進入https://www.google.com/這個網址,右下角有設定

油猴指令碼:網盤搜尋引擎聚合

首先安裝油猴指令碼chrome:【油猴指令碼外掛】。chrome或者瀏覽器也可以去【油猴指令碼官網】下載。 裝好以後點選新增新指令碼:將下面的程式碼複製進來,然後點[檔案]-[儲存],即可使用該指令碼程式碼首先在guihub上的分享,在這裡我也直接貼出程式碼: // ==UserScript== // @

油猴指令碼(tampermonkey):網盤搜尋引擎聚合

首先安裝油猴指令碼(tampermonkey)chrome:【油猴指令碼(tampermonkey)外掛】。chrome或者其他瀏覽器也可以去【油猴指令碼(tampermonkey)官網】下載。 程式碼首先在greasyfork上的分享 其次在吾愛油猴上的分享 再在guihub上的分享 最後我直接貼上

JS實現輸入框類似搜索的智慧提示效果

1.html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

類似的搜尋框的下拉的匹配使用最簡單的方式

在做專案的時候,需要用到那種模糊查詢的時候了,但是使用模糊查詢迴圈的查詢資料彷彿顯得不是那麼的現實,也就從網上找了一下資源,看了幾個不錯的例子,挑出了我最欣賞的一個例子來解析一下吧。 我們使用的是jQuery Autocomplete外掛 需要引入JQuery-UI的js和css等

【隨筆】網站被搜尋引擎爬取crawl-66-249-79-2

我正在公網網站上測試時,每當檢視日誌時,都會發現除了我的訪問,還出現了許多陌生訪問。於是進入後臺檢視到底是誰在訪問。 輸入命令netstat: 從圖中可以看到,有一個叫做crawl-66-249-79-2的機器跟我的網站建立了多個連線。 於是百度查詢這個名稱,才知道這是谷歌的爬蟲。 伺服器