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

Nutch是基于Lucene實現(xiàn)的搜索引擎汉形。包括全文搜索和Web爬蟲。Lucene為Nutch提供了文本索引和搜索的API。

1.有數(shù)據(jù)源涌穆,需要為這些數(shù)據(jù)提供一個搜索頁面。最好的方式是直接從數(shù)據(jù)庫中取出數(shù)據(jù)并用Lucene API 建立索引雀久,因為你不需要從別的網(wǎng)站抓取數(shù)據(jù)宿稀。
2.沒有本地數(shù)據(jù)源,或者數(shù)據(jù)源非常分散的情況下赖捌,就是需要抓別人的網(wǎng)站祝沸,則使用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

啟動后訪問 http://localhost:8080 就可以看到web服務器正常越庇。14339

2.部署nutch
這里nutch用1.2版本罩锐,雖然現(xiàn)在已經(jīng)很高版本了,但是1.2以上已經(jīng)沒有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.爬取數(shù)據(jù)

nutch目錄下,新建文件url.txt萍聊,把我們要抓的網(wǎng)站填入问芬,內(nèi)容

https://www.hicool.top/

有個過濾規(guī)則,我們上一步填入的網(wǎng)站寿桨,需要經(jīng)過這個規(guī)則過濾才可抓取此衅,否則不能。修改過濾規(guī)則亭螟,查看conf/craw-urlfilter.txt文件

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

這其實是一個正則表達式挡鞍,把加號那一行,改為僅僅允許自己網(wǎng)站通過

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

這樣可以只把自己的網(wǎng)站抓下來了预烙。修改conf/nutch-site.xml文件墨微,在configuration標簽內(nèi)增加如下索引目錄屬性,指定檢索器讀取數(shù)據(jù)的路徑扁掸。另外增加一個http.agent.name和一個http.robots.agents節(jié)點翘县,否則不能抓取。因為nutch遵守了 robots協(xié)議谴分,在爬行人家網(wǎng)站的時候锈麸,把自己的信息提交給被爬行的網(wǎng)站以供識別。

<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網(wǎng)站抓取的支持,如果要開啟僧凰,添加如下內(nèi)容到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網(wǎng)頁探颈,至于別的插件都是一些過濾解析網(wǎng)頁的。添加了插件之后训措,就可以爬https的網(wǎng)站了伪节。目前已有的協(xié)議及支撐插件如下:

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

Nutch 的爬蟲有兩種方式
? 爬行企業(yè)內(nèi)部網(wǎng)(Intranet crawling)。針對少數(shù)網(wǎng)站進行绩鸣,用 crawl 命令怀大。
? 爬行整個互聯(lián)網(wǎng)。 使用低層的 inject, generate, fetch 和 updatedb 命令呀闻,具有更強的可控制性化借。

我們使用crawl命令,抓數(shù)據(jù)

[root@localhost 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

上面的過程太長捡多,我略過了很多蓖康。參數(shù)含義說明如下:
-dir 指定存放爬行結果的目錄铐炫,本次抓取結果數(shù)據(jù)存放到sports目錄中;
-depth 表明需要抓取的頁面深度蒜焊,本次抓取深度為10層倒信;
-topN 表明只抓取前N個url,本次抓取為取每一層的前100個頁面泳梆;
-threads 指定Crawl采取下載的線程數(shù)鳖悠,我用這個一直抓不到數(shù)據(jù),就把它去掉了优妙。

根據(jù)下載過程可以看出nutch爬取網(wǎng)頁并建立索引庫的過程如下:
1)插入器(Injector)向網(wǎng)頁數(shù)據(jù)庫添加起始根URL乘综;
2)按照要求抓取的層數(shù),用生成器(Generator)生成待下載任務鳞溉;
3)調用獲取器(Fetcher)瘾带,按照指定線程數(shù)實際下載相應頁面;
4)調用頁面分析器(ParseSegment)熟菲,分析下載內(nèi)容;
5)調用網(wǎng)頁數(shù)據(jù)庫管理工具(CrawlDb)朴恳,把二級鏈接添加到庫中等待下載抄罕;
6)調用鏈接分析工具(LinkDb),建立反向鏈接于颖;
7)調用索引器(Indexer)呆贿,利用網(wǎng)頁數(shù)據(jù)庫、鏈接數(shù)據(jù)庫和具體下載的頁面內(nèi)容森渐,創(chuàng)建當前數(shù)據(jù)索引做入;
8)調用重復數(shù)據(jù)刪除器(DeleteDuplicates),刪除重復數(shù)據(jù)同衣;
9)調用索引合并器(IndexMerger)竟块,把數(shù)據(jù)合并到歷史索引庫中。

本地測試下搜索結果耐齐,搜關鍵字“1”

[root@localhost 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>

把我們上一步抓取數(shù)據(jù)的存放路徑配置到tomcat下,重啟tomcat辕翰,就可以在瀏覽器中搜索了夺衍。


4.篩選鏈接

有些鏈接我們需要抓取,有些我們則需要排除掉喜命。怎樣才能有一個篩選機制沟沙,過濾掉冗余的鏈接呢河劝?

編輯conf/regex-urlfilter.txt

# skip file: ftp: and mailto: urls
#過濾掉file:ftp等不是html協(xié)議的鏈接
-^(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.
-[?*!@=] 過濾掉汗特殊字符的鏈接,因為要爬取更多的鏈接尝胆,比如含丧裁?=的鏈接

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

# accept anything else
#接受所有的鏈接,這里可以修改為只接受自己規(guī)定類型的鏈接
+.

我現(xiàn)在只想抓取 https://www.hicool.top/article/324 類似這樣的含衔,只把 /article/* 下的內(nèi)容抓出來的需求煎娇。修改如下

# accept anything else
+^https:\/\/www\.hicool\.top\/article\/.*$

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

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

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

抓取動態(tài)內(nèi)容

我們平常訪問網(wǎng)站的時候杭隙,往往有"?"以及后面帶參數(shù)哟绊,這種動態(tài)的內(nèi)容默認也不抓取,需要配置痰憎。

在conf下面的2個文件:regex-urlfilter.txt票髓,crawl-urlfilter.txt

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

這段意思是跳過在連接中存在? * ! @ = 的頁面,因為默認是跳過所以铣耘,在動態(tài)頁中存在洽沟?一般按照默認的是不能抓取到的∥舷福可以在上面2個文件中都注釋掉:

# -[?*!@=]

另外增加允許的一行

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

意思是抓取時候允許抓取連接中帶 ? = & 這三個符號的連接
注意:兩個文件都需要修改裆操,因為NUTCH加載規(guī)則的順序是crawl-urlfilter.txt-> regex-urlfilter.txt

5.按詞劃分和中文分詞

看看上文最后的效果,你會發(fā)現(xiàn)炉媒,搜索是按單個字來區(qū)分的踪区,你輸入一句話,每個字都被單獨搜了一遍吊骤,導致不想關的信息太冗余缎岗。原來,nutch默認對中文按字劃分水援,而不是按詞劃分密强。
so,我們要達到按詞劃分以減少冗余的目的蜗元,則:
1.修改源代碼或渤。直接對Nutch分詞處理類進行修改,調用已寫好的一些分詞組件進行分詞奕扣。
2.使用分詞插件薪鹦。按照Nutch的插件編寫規(guī)則重新編寫或者添加中文分詞插件。

這里我使用修改源碼方式,得下載源碼重新編譯了池磁。關于 IKAnalyzer3.2.8.jar 這個包奔害,我是在網(wǎng)上搜到下載的〉叵ǎ可以看這篇 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語言分析器按照規(guī)則自動生成的源代碼却特。確保安裝了該工具扶供。

[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

編譯成功左腔,產(chǎn)生一個build目錄

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

再生產(chǎn)war包

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

我們的編譯就大功告成了。剩下的就是重復跟上文部署一個搜索引擎的步驟捅儒,過程略。有一點需要說明振亮,新的搜索界面巧还,輸入關鍵詞進行搜索,這時會出現(xiàn)空白頁坊秸。還需要修改 /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,需要注意褒搔。重啟后的分詞效果



可以看到已經(jīng)以“設計模式”阶牍、“設計”、“模式”這些詞看分關鍵詞搜索了星瘾,OK走孽,成功!

問題

每次重新爬后琳状,要重啟tomcat才能順利訪問

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

特么的磕瓷,網(wǎng)上看一堆類似這么寫的

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次符匾,配置了一堆東西,最后自己發(fā)現(xiàn)瘩例, -treads 10 這個參數(shù)有大問題啊胶,帶上它怎么都失敗,去掉立刻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

參考


創(chuàng)建于 2017-10-19 北京南吮,更新于 2017-10-23 北京

該文章在以下平臺同步

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末琳彩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子部凑,更是在濱河造成了極大的恐慌露乏,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涂邀,死亡現(xiàn)場離奇詭異瘟仿,居然都是意外死亡,警方通過查閱死者的電腦和手機比勉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門劳较,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人浩聋,你說我怎么就攤上這事观蜗。” “怎么了衣洁?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵墓捻,是天一觀的道長。 經(jīng)常有香客問我坊夫,道長砖第,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任环凿,我火速辦了婚禮梧兼,結果婚禮上,老公的妹妹穿的比我還像新娘拷邢。我一直安慰自己袱院,他們只是感情好,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著忽洛,像睡著了一般腻惠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上欲虚,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天集灌,我揣著相機與錄音,去河邊找鬼复哆。 笑死欣喧,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的梯找。 我是一名探鬼主播唆阿,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼锈锤!你這毒婦竟也來了驯鳖?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤久免,失蹤者是張志新(化名)和其女友劉穎浅辙,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阎姥,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡记舆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了呼巴。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泽腮。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖衣赶,靈堂內(nèi)的尸體忽然破棺而出盛正,到底是詐尸還是另有隱情,我是刑警寧澤屑埋,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站痰滋,受9級特大地震影響摘能,放射性物質發(fā)生泄漏。R本人自食惡果不足惜敲街,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一团搞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧多艇,春花似錦逻恐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拨匆。三九已至,卻和暖如春挽拂,著一層夾襖步出監(jiān)牢的瞬間惭每,已是汗流浹背碱屁。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工宪摧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人奈泪。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓绒北,卻偏偏與公主長得像黎侈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子闷游,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容