Nutch[1] 是一個開源Java實現的搜索引擎,它提供了咱們運行本身的搜索引擎所需的所有工具,包括全文搜索和Web爬蟲。
Solr[2]是一個基於Lucene的全文搜索服務器,它對外提供相似於Web-service的API查詢接口,是一款很是優秀的全文搜索引擎。html
簡單地講,nutch重在提供數據源採集(Web爬蟲)能力,輕全文搜索(lucene)能力;solr是lucene的擴展,亦是nutch的全文搜索的擴展。重在將nutch的爬取結果,經過其對外提供檢索服務。java
支持hadoop,能夠經過hadoop,得到分佈式爬蟲的能力。本文重點介紹nutch的原力,關於分佈式爬蟲,將在後續章節中介紹。另外,nutch-2.x系列支持hbase,能夠根據自身的須要靈活選擇。須要說明的是兩版的用法是不一樣的,nutch-2.x要更爲複雜。在使用nutch-2.x以前,最好具有nutch-1.x的基礎。node
截止發稿時是最新版本,可參考官網的解釋,這裏沒什麼要說的。web
Ubuntu14.04x64 或 Centos6.5x64, 應用程序採用二進制安裝,不要求編譯環境數據庫
vim /etc/profile # set for java export JAVA_HOME=/opt/jdk1.8.0_111 #二進制包已經解壓安裝到該路徑 export PATH=$PATH:$JAVA_HOME/bin export CLASSPATH=.:$CLASSPATH:$JAVA_HOME/lib export _JAVA_OPTIONS="Xmx2048m XX:MaxPermSize=512m Djava.awt.headless=true"
注:java的安裝方法選擇二進制包便可,本文再也不贅述apache
vim /etc/profile export NUTCH_RUNTIME_HOME='/opt/apache-nutch-1.13' export PATH=$NUTCH_RUNTIME_HOME/bin:$PATH export APACHE_SOLR_HOME='/opt/solr-6.6.0' #單引號不能少 export PATH=$APACHE_SOLR_HOME/bin:$PATH export CLASSPATH=.:$CLASSPATH:$APACHE_SOLR_HOME/server/lib
source /etc/profile #加載到環境
vim
wget http://mirror.bit.edu.cn/apache/lucene/solr/6.6.0/solr-6.6.0.tgz cat solr-6.6.0.tgz |(cd /opt; tar xzfp -) solr status #注:若是執行結果不正常,執行`source /etc/profile`和檢查該文件的內容 No Solr nodes are running. #啓動solr服務 solr start -force #-force:強制以root身份執行,生產環境請勿使用該參數 #中止solr服務 solr stop
安裝完畢。瀏覽器
cd ${APACHE_SOLR_HOME} cp -r server/solr/configsets/basic_configs server/solr/configsets/nutch cp ${NUTCH_RUNTIME_HOME}/conf/schema.xml server/solr/configsets/nutch/conf mv server/solr/configsets/nutch/conf/managed-schema server/solr/configsets/nutch/conf/managed-schema.backup #啓動solr服務 solr start #建立nutch core solr create -c nutch -d server/solr/configsets/nutch/conf/ -force #-force:強制以root身份執行,生產環境請勿使用該參數 建立過程並不是一路順風,整個過程充滿了各類bug,從這個角度考慮,生產環境中有必要更換到solr的穩定版,好在這些坑已經趟過: 問題1:Caused by: Unknown parameters: {enablePositionInc rements=true} 具體信息: Copying configuration to new core instance directory: /opt/solr-6.6.0/server/solr/nutch Creating new core 'nutch' using command: http://localhost:8983/solr/admin/cores?action=CREATE&name=nutch&instanceDir=nutch ERROR: Error CREATEing SolrCore 'nutch': Unable to create core [nutch] Caused by: Unknown parameters: {enablePositionIncrements=true} 解決辦法: vim server/solr/configsets/nutch/conf/schema.xml 找到並去掉enablePositionIncrements=true 問題2:ERROR: Error CREATEing SolrCore 'nutch': Unable to create core [nutch] Caused by: defaultSearchField has been deprecated and is incompatible with configs with luceneMatchVersion >= 6.6.0. Use 'df' on requests instead. 解決辦法: vim server/solr/configsets/nutch/conf/solrconfig.xml 將luceneMatchVersion版本修改成6.2.0 問題3:org.apache.solr.common.SolrException: fieldType 'booleans' not found in the schema 解決辦法: vim /opt/solr-6.6.0/server/solr/configsets/nutch/conf/solrconfig.xml 找到booleans,替換成boolean,以下: <lst name="typeMapping"> <str name="valueClass">java.lang.Boolean</str> <str name="fieldType">boolean</str> </lst> Then it will work.. 問題3之後,會發生多起相似事件,以下: ERROR: Error CREATEing SolrCore 'nutch': Unable to create core [nutch] Caused by: fieldType 'tdates' not found in the schema ERROR: Error CREATEing SolrCore 'nutch': Unable to create core [nutch] Caused by: fieldType 'tlongs' not found in the schema ERROR: Error CREATEing SolrCore 'nutch': Unable to create core [nutch] Caused by: fieldType 'tdoubles' not f ound in the schema 參照問題3的方法,一次性去掉''中關鍵字的複數形式便可。 問題4:ERROR: Core 'nutch' already exists! Checked core existence using Core API command: http://localhost:8983/solr/admin/cores?action=STATUS&core=nutch 解決辦法: solr delete -c nutch #刪除core 'nutch' 若是刪除完,還提示這個錯誤,這是因爲每次修改完配置文件,須要重啓下solr服務,更新下狀態。 最終的執行結果: solr create -c nutch -d server/solr/configsets/nutch/conf/ -force Copying configuration to new core instance directory: /opt/solr-6.6.0/server/solr/nutch Creating new core 'nutch' using command: http://localhost:8983/solr/admin/cores?action=CREATE&name=nutch&instanceDir=nutch { "responseHeader":{ "status":0, "QTime":3408}, "core":"nutch"} 執行成功! 在瀏覽器中訪問 http://localhost:8983/solr/#/ 能夠看到名稱爲nutch的core
cd /opt/solr-6.6.0/server cat etc/realm.properties # # 這個文件定義用戶名,密碼和角色 # # 格式以下 # <username>: <password>[,<rolename> ...] # #userName: password,role yourname: yourpass,admin
cat contexts/solr-jetty-context.xml <?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd"> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Set name="contextPath"><Property name="hostContext" default="/solr"/></Set> <Set name="war"><Property name="jetty.base"/>/solr-webapp/webapp</Set> <Set name="defaultsDescriptor"><Property name="jetty.base"/>/etc/webdefault.xml</Set> <Set name="extractWAR">false</Set> <Get name="securityHandler"> <Set name="loginService"> <New class="org.eclipse.jetty.security.HashLoginService"> <Set name="name">Solr Admin Access</Set> <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set> </New> </Set> </Get> </Configure>
vim solr-webapp/webapp/WEB-INF/web.xml <!-- Get rid of error message --> <security-constraint> ... </security-constraint> <security-constraint> <web-resource-collection> <web-resource-name>Solr auth enticated application</web-resource-name> <!--描述--> <url-pattern>/</url-pattern> <!-- 驗證的網頁的位置--> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> <!-- 驗證的角色,別寫成用戶名,若有多個角色能夠寫多個role-name 標籤--> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <!-- 關鍵--> <realm-name>Solr Admin Access</realm-name> </login-config> </web-app> 重啓solr服務 solr stop && solr start -force 在瀏覽器中訪問solr http://localhost:8983/solr/nutch/ 能夠看到要求登陸的界面
wget http://mirrors.hust.edu.cn/apache/nutch/1.13/apache-nutch-1.13-bin.tar.gz cat apache-nutch-1.13-bin.tar.gz |(cd /opt; tar xzfp -) nutch -help #注:若是執行結果不正常,執行`source /etc/profile`和檢查該文件的內容
安裝完畢。安全
以爬取http://nutch.apache.org站點爲例,配置以下:服務器
vim $NUTCH_RUNTIME_HOME/conf/nutch-site.xml <property> <name>http.agent.name</name> <value>My Nutch Spider</value> </property>
#配置indexer-solr插件 #個人方法是替換indexer-elastic爲indexer-solr插件 sed -i 's/indexer-elastic/indexer-solr/g' $NUTCH_RUNTIME_HOME/conf/nutch-site.xml #注意:官方文檔不是像我這樣作的,請按照個人方法配置,或者註釋掉indexer-elastic,不然會深受其害,踩坑過程後面會說
#爲方便修改配置文件,選擇conf文件夾做爲數據的存儲路徑 cd $NUTCH_RUNTIME_HOME/conf mkdir -p urls #存儲要爬取的URLS列表,每行只寫一個url,能夠多行 cd urls echo 'http://nutch.apache.org/' > seed.txt #地址能夠是靜態的連接,也能夠是動態的連接
vim regex-urlfilter.txt 將光標移到文件末尾,將下列內容: # accept anything else +. 替換爲: # accept anything else +^http://([a-z0-9]*\.)*nutch.apache.org/ #這將包含帶有域名前綴的url,好比,http://3w.nutch.apache.org
vim crawl-urlfilter.txt regex-urlfilter.txt
替換: # skip URLs containing certain characters as probable queries, etc. -[?*!@=] 爲: # accept URLs containing certain characters as probable queries, etc. +[?=&]
注: conf下有各類配置文件,涉及各類爬取規則和正則過濾器。將在後續的文章中詳細說明
抓取程序自動在用戶指定目錄下面創建爬取目錄,其目錄下能夠看到crawldb,segments,linkdb子目錄
crawldb目錄下面存放下載的URL,以及下載的日期、過時時間
linkdb目錄存放URL的關聯關係,是下載完成後分析時建立的,經過這個關聯關係能夠實現相似google的pagerank功能
segments目錄存儲抓取的頁面,這些頁面是根據層級關係分片的。既segments下面子目錄的個數與獲取頁面的層數有關係,若是指定「-depth」參數是10層,這個目錄下就有10層,結構清晰並防止文件過大。
segments目錄裏面有6個子目錄,分別是:
「crawl_generate」 生成要獲取的一組URL的名字,既生成待下載的URL的集合 「crawl_fetch」 包含獲取每一個UR L的狀態 」content「 包含從每一個URL檢索的原始內容 「parse_text」 包含每一個URL的解析文本(存放每一個解析過的URL的文本內容) 「parse_data」 包含從每一個URL分析的外部連接和元數據 「crawl_parse」 包含用於更新crawldb的outlink URL(外部連接庫)
爬取過程包括
injector -> generator -> fetcher -> parseSegment -> updateCrawleDB -> Invert links -> Index -> DeleteDuplicates -> IndexMerger 1. 根據以前建好的URL列表文件,將URL集註入crawldb數據庫---inject 2. 根據crawldb數據庫建立抓取列表---generate 3. 執行抓取,獲取網頁信息---fetch 4. 執行解析,解析網頁信息---parse 5. 更新數據庫,把獲取到的頁面信息存入數據庫中---updatedb 6. 重複進行2~4的步驟,直到預先設定的抓取深度。---這個循環過程被稱爲「產生/抓取/更新」循環 7. 根據sengments的內容更新linkdb數據庫---invertlinks 8. 創建索引---index
nutch inject crawl/crawldb urls
nutch generate crawl/crawldb crawl/segments
s1=`ls -d crawl/segments/2* | tail -1` echo $s1 nutch fetch $s1
nutch parse $s1
nutch updatedb crawl/crawldb $s1
重複2-4的過程,抓取下一層頁面
演示過程當中,爲了節約時間,咱們約定一個參數,只抓取前 top 1000 的頁面
nutch generate crawl/crawldb crawl/segments -topN 1000 s2=`ls -d crawl/segments/2* | tail -1` echo $s2 nutch fetch $s2 nutch parse $s2
updatedb:
nutch updatedb crawl/crawldb $s2
重複2-4的過程,抓取下下層的頁面
一樣只取前1000個頁面進行抓取
nutch generate crawl/crawldb crawl/segments -topN 1000 s3=`ls -d crawl/segments/2* | tail -1` echo $s3 nutch fetch $s3 nutch parse $s3
updatedb:
nutch updatedb crawl/crawldb $s3
這樣咱們總共抓取了三個層級深度的頁面
ls crawl/segments/ 20170816191100 20170816191415 20170816192100
nutch invertlinks crawl/linkdb -dir crawl/segments
nutch index -Dsolr.server.url=http://用戶名:密碼@localhost:8983/solr/nutch crawl/crawldb/ -linkdb crawl/linkdb/ crawl/segments/20170816191100/ -filter -normalize -deleteGone #這裏的「用戶名:密碼」是solr的jetty下的 值得一提的是,若是按照官方標準語法,上面命令會變爲: nutch index -Dsolr.auth.username="yourname" -Dsolr.auth.password="yourpassword" -Dsolr.server.url=http://localhost:8983/solr/nutch crawl/crawldb/ -linkdb crawl/linkdb/ crawl/segments/20170816191100/ -filter -normalize -deleteGone 這裏會提示語法錯誤,在官網和google上尚未更好的解決辦法。我已經把上面的方法更新到 http://lucene.472066.n3.nabble.com/Nutch-authentication-problem-to-solr-td4251336.html#a4351038 可能其它版本沒有這個問題。 最終的推送結果以下: nutch index -Dsolr.server.url=http://xxx:xxx@localhost:8983/solr/nutch crawl/crawldb/ -linkdb crawl/linkdb/ crawl/segments/20170816191100/ -filter -normalize -deleteGone Segment dir is co mplete: crawl/segments/20170816191100. Indexer: starting at 2017-08-17 18:22:26 Indexer: deleting gone documents: true Indexer: URL filtering: true Indexer: URL normalizing: true Active IndexWriters : SOLRIndexWriter solr.server.url : URL of the SOLR instance solr.zookeeper.hosts : URL of the Zookeeper quorum solr.commit.size : buffer size when sending to SOLR (default 1000) solr.mapping.file : name of the mapping file for fields (default solrindex-mapping.xml) solr.auth : use authentication (default false) solr.auth.username : username for authentication solr.auth.password : password for authentication Indexing 1/1 documents Deleting 0 documents Indexer: number of documents indexed, deleted, or skipped: Indexer: 1 indexed (add/update) Indexer: finished at 2017-08-17 18:22:32, elapsed: 00:00:05
在瀏覽器中訪問solr
http://localhost:8983/solr/
crawl -i -D solr.server.url=http://用戶名:密碼@localhost:8983/solr/ urls/ crawl/ 2
https://wiki.apache.org/nutch/NutchTutorial#Install_Nutch [1]https://wiki.apache.org/nutch/ [2]https://wiki.apache.org/solr/