InjectしたURLのみクロールする - Nutch調査録
-
概要
Nutchは普通に使うとリンクを次々に追ってページを取得していく。
先日、「テキストファイルに保存してある数万件のURLをFetchしたい。でもリンクは追って欲しくない。リンクの情報は欲しい」というわがままな処理をしたくなった。
どうするのが正解かイマイチよくわからなかったけど(というかその処理をNutchでさせるのが正解かどうかから考えないといけない気もする)、とりあえずこんな風に書いたらうまくいった。
@Author mwSoft
@Date 2010/12/16
@Env Nutch1.2/Fedora14 -
設定の説明
crawl時のtopNの回数をInjectしたURLの数と合わせて実行すれば、優先的にInjectしたURLたちがFetchされるはず。ただ、スコアの都合によっては他のURLを見に行ってしまう可能性もある。
リンク先をクロール対象に含めないようにするには、updatedb時にcrawldbに加わらないようにするか、generate時にsegmentsのcrawl_generateに加わらないようにする必要がある。
updatedb時の処理(CrawlDbクラス)には使えそうなものは見当たらなかったけど、generate時の処理(Generatorクラス)に面白い記述があった。
PUBLIC static final String GENERATOR_MIN_SCORE = "generate.min.score"; scoreThreshold = job.getFloat(GENERATOR_MIN_SCORE, Float.NaN); if (scoreThreshold != Float.NaN && sort < scoreThreshold) return;
どうやらgenerate.min.scoreという値を設定すると、そのスコア以下のURLをFetch対象から外してくれるらしい。
このgenerate.min.scoreはconf/nutch-default.xmlには記述されていない。
-
設定の変更
generate時に利用されるスコアはたいてい0.1程度の小さい数値が設定されている。
なのでInjectされるスコアはデフォルトの1.0で十分なはずだけど、今回は余裕を持ってデフォルト値を2.0にした上で、1.9以下をフィルタリングする。
<property> <name>db.score.injected</name> <value>2.0</value> </property> <property> <name>generate.min.score</name> <value>1.9</value> </property>
db.score.injectedはInjectされた時に設定されるスコアのデフォルト値。これでInjectされたURLのスコアは2.0になり、1.9以下のURLはFetch対象から排除されることになる。
それからこれだけの設定だとリダイレクトが起きていた時に先を追って行ってくれない。ので、以下の設定をする。
<property> <name>http.redirect.max</name> <value>5</value> </property>
http.redirect.maxは、リダイレクトの最大回数を決める。これが1以上になっていると、指定回数分だけimmediatelyな感じにリダイレクトしてFetchしてくれる。
リダイレクトが5回以上発生する場合は追いきれないけど、そんなURLは個人的に取れなくてもいいやと思ったのでこの数字にしている。お好みで10とか20を書いてもいいと思う。
-
実際の動作の確認
まず、InjectするURLを用意。リダイレクトも含むようにTwitterで検索して拾ってきた短縮URLを適当に入れておく。
$ mkdir url_list $ touch url_list/urls.txt $ vi url_list/urls.txt http://www.itmedia.co.jp/ http://www.atmarkit.co.jp/ http://itpro.nikkeibp.co.jp/ http://journal.mycom.co.jp/ http://gihyo.jp/ http://bit.ly/flGeMi http://bit.ly/e3x5G1 http://bit.ly/cbVzB1 http://ustre.am/rfne http://ustre.am/kcYw
この設定で何周かクロールさせてみて、指定したURLと短縮URLのリダイレクト先以外が取得されていなかったらOKということで。
というわけで、実行。topNはあえて多めに設定。
$ bin/nutch crawl url_list -dir inject_crawl -depth 10 -topN 20
結果を見てみる。
$ ls inject_crawl/segments/ 20101216004822
depthを10に指定したのに取れた結果は1つだけになっている。どうやらちゃんとリンクを追わずに居てくれているらしい。
中身をdumpしてみる。
$ s1=`ls -1 inject_crawl/segments | head -1` $ bin/nutch readseg -dump inject_crawl/segments/$s1 dump -nocontent $ vi dump/dump http://bit.ly/cbVzB1 → Status: 36 (fetch_redir_perm) http://gihyo.jp/ → Status: 33 (fetch_success) http://gihyo.jp/text/javascript → Status: 67 (linked)
上記のような感じで、Injectした短縮URLは36(リダイレクト)、Injectした普通のURLは33(Fetch成功)、それ以外のURLは67 (linked)が設定されている。
67(linked)がたくさん居て見づらいと思うので、もう少し解りやすいようにgrepで見てみる。
$ grep "Status: 33" dump/dump
Status 33(fetch_success)がInjectした件数と同じく10件存在する。
ついでにlinked以外をgrepしてみる。
$ grep "Status: " dump/dump | grep -v linked
35(fetch_redir_temp)がけっこう起きてるみたいだけど、ちゃんと最後まで追いかけてくれたらしい。ということで、ざっと動かした感じではこの設定で大丈夫そう。