運作Nutch的時候提示Generator: 0 records selected for fetching, exiting ...然後程式退出,怎麼回事呢?
原因多種多樣,歸根結底就是CrawlDB中的URL經過爬蟲抓取排程器(預設是org.apache.nutch.crawl.DefaultFetchSchedule)判斷,斷定都不應該去抓,是以,Stop The World。
我們使用指令如下指令來檢視CrawlDB的統計資訊:
bin/nutch readdb data/crawldb -stats
結果如下:
CrawlDb statistics start: data/crawldb
Statistics for CrawlDb: data/crawldb
TOTAL urls: 347457
retry 0: 346506
retry 1: 951
min score: 0.0
avg score: 6.605134E-6
max score: 1.0
status 1 (db_unfetched): 951
status 2 (db_fetched): 337818
status 3 (db_gone): 3637
status 4 (db_redir_temp): 5006
status 5 (db_redir_perm): 45
CrawlDb statistics: done
我們發現db_unfetched狀态的URL還有951個,怎麼不抓了呀?呵呵,别急,繼續看,發現retry 1的URL也有951個,retry 1是什麼東東呢?就是抓取失敗了,等待1天(預設)後再次去抓的URL,哦,現在明白了吧,這些db_unfetched狀态的URL其實都已經抓過了,不過都抓取失敗了,因為隻有抓取成功的URL的狀态才會變為非db_unfetched的其他狀态。
弄明白了為什麼爬蟲退出的原因之後,還有疑問嗎?對這些抓取失敗的URL是什麼原因導緻的失敗不感興趣嗎?
我們把CrawlDB中db_unfetched狀态的URL導出為文本檔案,看看到底是些什麼URL,失敗的原因都是些什麼,用如下指令:
bin/nutch readdb data/crawldb -dump crawldb_dump -format normal -status
指令執行完畢我們就可以看這個導出的文本檔案裡面的内容了,檔案位于目前路徑下crawldb_dump/part-00000。
我們要确認一下導出的文本檔案的db_unfetched狀态的URL的數目是否為951,用如下指令:
cat crawldb_dump/* | grep db_unfetched | wc
結果如下:
951 2853 23775
數目沒問題。然後使用如下指令找到抓取失敗的資訊:
cat crawldb_dump/* | grep exception | wc
結果如下:
951 7300 91535
數目也是951,這就說明了狀态為db_unfetched的951條URL都抓過了,不幸的是都失敗了。
接着我們要從這951條失敗資訊中提取出抓取失敗的類型,使用如下指令去除重複的失敗資訊:
cat crawldb_dump/* | grep exception | sort | uniq | wc
結果如下:
35 242 4034
去重之後隻剩下35條了,太好了,人眼可以識别了呀,呵呵,我們進一步去除以:隔開的前三個字段,這3個字段每條資料都相同,使用以下指令:
cat crawldb_dump/* | grep exception | sort | uniq | awk -F ":" '{print $4 $5}' | uniq | more
結果如下:
Http code=403, url=http//bgt.mof.gov.cn/mofhome/mof/1557/
Http code=403, url=http//bgt.mof.gov.cn/mofhome/mof/zhengwuxinxi/tianbanli/2006tabl/rdjydf/
Http code=403, url=http//bgt.mof.gov.cn/mofhome/mof/zhengwuxinxi/tianbanli/2006tabl/zs/
Http code=403, url=http//bgt.mof.gov.cn/mofhome/mof/zhengwuxinxi/tianbanli/2006tabl/zxtadf/
Http code=403, url=http//bgt.mof.gov.cn/mofhome/mof/zhuantihuigu/czgg0000_1/spjl/
Http code=403, url=http//gjs.mof.gov.cn/mofhome/mof/1557/
Http code=403, url=http//gjs.mof.gov.cn/mofhome/mof/zhengwuxinxi/tianbanli/2006tabl/rdjydf/
Http code=403, url=http//gjs.mof.gov.cn/mofhome/mof/zhengwuxinxi/tianbanli/2006tabl/zs/
Http code=403, url=http//gjs.mof.gov.cn/mofhome/mof/zhengwuxinxi/tianbanli/2006tabl/zxtadf/
Http code=403, url=http//gjs.mof.gov.cn/mofhome/mof/zhuantihuigu/czgg0000_1/spjl/
Http code=403, url=http//gjs.mof.gov.cn/pindaoliebiao/dhjz/qqhzjz/20Ghy/czyhhzhy/5156/
Http code=403, url=http//gjs.mof.gov.cn/pindaoliebiao/zcyd/dhjz/20Ghy/czyhhzhy/5156/
Http code=403, url=http//kjhx.mof.gov.cn/gongzhongcanyu/
Http code=403, url=http//sn.mof.gov.cn/lanmudaohang/zixz/
Http code=403, url=http//wjb.mof.gov.cn/pindaoliebiao/
Http code=403, url=http//www.mof.gov.cn/1557/
Http code=403, url=http//www.mof.gov.cn/zhengwuxinxi/tianbanli/2006tabl/rdjydf/
Http code=403, url=http//www.mof.gov.cn/zhengwuxinxi/tianbanli/2006tabl/zs/
Http code=403, url=http//www.mof.gov.cn/zhengwuxinxi/tianbanli/2006tabl/zxtadf/
Http code=403, url=http//www.mof.gov.cn/zhuantihuigu/czgg0000_1/spjl/
Http code=403, url=http//xxzx.mof.gov.cn/zaixianfuwuxxzx/
Http code=403, url=http//xxzx.mof.gov.cn/zhuantilanmuxxzx/
Http code=403, url=http//zcpg.mof.gov.cn/skzd/skjs/
Http code=403, url=http//zcpg.mof.gov.cn/zywk/pgll/
Http code=403, url=http//zhs.mof.gov.cn/zhuantilanmu/
Http code=500, url=http//zcgl.mof.gov.cn/
java.net.ConnectException Connection refused
java.net.SocketException Connection reset
java.net.SocketTimeoutException connect timed out
java.net.SocketTimeoutException Read timed out
java.net.UnknownHostException czxh.mof.gov.cn
java.net.UnknownHostException docsvr.mof.gov.cn
java.net.UnknownHostException shdk.mof.gov.cn
java.net.UnknownHostException www.hn.mof.gov.cn
java.net.UnknownHostException ysyj.mof.gov.cn
經過人工分析(自動分析不奏效了)發現了7種不同類型的抓取錯誤(注意:你的系統中跟我的可能不同):
Http code=403
Http code=500
Connection refused
Connection reset
connect timed out
Read timed out
java.net.UnknownHostException
分别使用這7種不同的抓取錯誤類型重新從導出的檔案中進行統計,結果仍然是951。
cat crawldb_dump/* | grep "connect timed out" | wc
cat crawldb_dump/* | grep "Read timed out" | wc
cat crawldb_dump/* | grep 'Http code=403' | wc
cat crawldb_dump/* | grep 'Connection refused' | wc
cat crawldb_dump/* | grep "Connection reset" | wc
cat crawldb_dump/* | grep java.net.UnknownHostException | wc
cat crawldb_dump/* | grep 'Http code=500' | wc
好了,分析完畢,貼一張更直覺完整的圖來結束文章:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuMzY3YmZ4YjN0MjNm1yY2QDOtQWY4MTLmhTO00COzQjY3cTY08CX1ATNw8CX1kDMw8CX05WZth2YhRHdh9CXkF2bsBXdvwVbvNmLllXZ0lmLywGZvw1LcpDc0RHaiojIsJye.png)