Nutch 1.5 + Solr 4.0 で DMOZ データベースの検索インデックスを作成する方法

NutchTutorial - Nutch Wiki をもとに、Nutch 1.5 + Solr 4.0 で DMOZ データベースのインデックスを作成して検索できるようにしてみた。

手順

大まかな手順は以下の通り。

  1. Nutch のインストール
  2. DMOZ データベースのダウンロード
  3. Nutch の設定・クローラ起動
  4. Solr のインストール
  5. Solr の設定・起動
  6. Nutch から SolrIndexer を起動

前提

  • OS : Ubuntu 10.04 LTS
  • Nutch : v1.5
  • Solr : v4.0

1. Nutch のインストール

まずは Nutch 1.5 をダウンロードする。

$ mkdir ~/src
$ cd ~/src
$ wget http://www.fightrice.com/mirrors/apache/nutch/1.5/apache-nutch-1.5-bin.tar.gz
$ mkdir -p ~/nutch-1.5/dmoz-example
$ cd ~/nutch-1.5/dmoz-example
$ tar zxvf ~/src/apache-nutch-1.5-bin.tar.gz

続いて JDK のセットアップ。JDK は openjdk にした。

$ sudo apt-get install openjdk-6-jdk
$ vi ~/.bashrc
# 行末に追加
export JAVA_HOME=/usr/lib/jvm/java-6-openjdk/
$ source ~/.bashrc

Nutch の実行コマンド bin/nutch に実行権限を追加しておく。

$ chmod +x bin/nutch

Nutch の設定を記載するための nutch-site.xml にクローラのエージェント名を設定する。

$ vi conf/nutch-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overrides in this file. -->

<configuration>
<property>
 <name>http.agent.name</name>
 <value>My Nutch Spider</value>
</property>
</configuration>

ここまででひとまず Nutch が動くようになるはず。Nutch の設定ファイル構成の詳細については Wiki を参照。

2. DMOZ データベースのダウンロード

次に、データソースとなる DMOZ のページをダウンロードして解凍する。

$ cd ~/src
$ wget http://rdf.dmoz.org/rdf/content.rdf.u8.gz
$ gunzip content.rdf.u8

3. Nutch の設定・クローラ起動

Nutch は bin/nutch というシェルスクリプトで実行する。この bin/nutch は Java のクラスファイル実行のためのラッパーであり、実行時にオプションを追加することで Nutch の動作を選択できる。

はじめに Nutch のパッケージに含まれている DmozParser を使って、DMOZ データベースから URL を抽出する。

$ cd ~/nutch-1.5/dmoz-example;
$ mkdir dmoz
$ bin/nutch org.apache.nutch.tools.DmozParser ~/src/content.rdf.u8 -subset 5000 > dmoz/urls

コマンドの "-subset 5000" とは、5000 件に 1 件の割合で URL をランダムに抽出するという意味。処理が終わるのに数分かかる。処理が終わったところで URL の件数 (dmoz/urls の行数) をカウントしてみた。たぶんこれはデータソースのバージョンによってばらつきがあるはず。

$ wc -l dmoz/urls
846 dmoz/urls
$ cat dmoz/urls | uniq | wc -l
833

次に、Nutch の Injector を使い dmoz/urls のリストを元に crawldb を初期化する。

$ bin/nutch inject crawl/crawldb dmoz

なお、crawldb に格納されている URL の件数は、Nutch のコマンドオプション readdb を使って確認できる。

$ bin/nutch readdb crawl/crawldb -stats
CrawlDb statistics start: crawl/crawldb
Statistics for CrawlDb: crawl/crawldb
TOTAL urls:	739  # なぜか減ってるけど無視
retry 0:	739
min score:	1.0
avg score:	1.0
max score:	1.0
status 1 (db_unfetched):	739
CrawlDb statistics: done

dump を取得したい場合は -dump で指定する。

$ bin/nutch readdb crawl/crawldb -dump out_dir
$ less out_dir/part-00000
http://1camp.com/       Version: 7
Status: 1 (db_unfetched)
Fetch time: Thu Jul 09 08:45:14 PDT 2012
Modified time: Wed Dec 31 16:00:00 PST 1969
Retries since fetch: 0
Retry interval: 2592000 seconds (30 days)
Score: 1.0
Signature: null
Metadata: 

http://4thandelm.com/   Version: 7
Status: 1 (db_unfetched)
Fetch time: Thu Jul 09 08:45:14 PDT 2012
...

crawldb ができたら、Generetor で fetch list を生成する。

$ bin/nutch generate crawl/crawldb crawl/segments
$ ls crawl/segments
20120709084939

fetch list は、新たに生成される segments ディレクトリ以下に作られる。セグメントディレクトリ名には、ディレクトリの作成日時が自動で与えられる。このディレクトリ名をシェルの変数に設定しておく。

$ s1=`ls -d crawl/segments/2* | tail -1`
$ echo $s1
crawl/segments/20120709084939

Fetcher を使ってフェッチリストの URL を順次フェッチする。

$ bin/nutch fetch $s1

さらに、取得したしたコンテンツを Parser でパースする。

$ bin/nutch parse $s1

segment の情報は bin/nutch readseg で参照できる。readseg のオプションは多様なので、詳細はヘルプを参考に。例えば http://1camp.com/ の情報を取り出すときは以下のようなコマンドを実行する。

$ bin/nutch readseg -get $s1 http://1camp.com/

Updatedb コマンドで既存のクロールデータベースをアップデート。

$ bin/nutch updatedb crawl/crawldb $s1

updatedb を使うと、既存のリストに加え、新たに初期の URL セットからリンクされている URL のセットがリストに加わる。crawldb のステータスを確認すると以下のように変更された。

$ bin/nutch readdb crawl/crawldb -stats
CrawlDb statistics start: crawl/crawldb
Statistics for CrawlDb: crawl/crawldb
TOTAL urls:	14009
retry 0:	13996
retry 1:	13
min score:	0.0
avg score:	0.091293596
max score:	3.376
status 1 (db_unfetched):	13283
status 2 (db_fetched):	614
status 3 (db_gone):	13
status 4 (db_redir_temp):	35
status 5 (db_redir_perm):	64
CrawlDb statistics: done

更新されたクロールデータベースをもとに、スコアが高い上位 1000 URL をターゲットに再度クロールを実行する。

$ bin/nutch generate crawl/crawldb crawl/segments -topN 1000
$ s2=`ls -d crawl/segments/2* | tail -1`
$ echo $s2
$ bin/nutch fetch $s2
$ bin/nutch parse $s2
$ bin/nutch updatedb crawl/crawldb $s2

セグメントディレクトリが一つ増え、クロールデータベースが更新されていることがわかる。

$ bin/nutch readdb crawl/crawldb -stats
CrawlDb statistics start: crawl/crawldb
Statistics for CrawlDb: crawl/crawldb
TOTAL urls:	21210
retry 0:	21185
retry 1:	25
min score:	0.0
avg score:	0.06809505
max score:	3.997
status 1 (db_unfetched):	19496
status 2 (db_fetched):	1497
status 3 (db_gone):	50
status 4 (db_redir_temp):	63
status 5 (db_redir_perm):	104
CrawlDb statistics: done

再度実行。

$ bin/nutch generate crawl/crawldb crawl/segments -topN 1000
$ s3=`ls -d crawl/segments/2* | tail -1`
$ echo $s3
$ bin/nutch fetch $s3
$ bin/nutch parse $s3
$ bin/nutch updatedb crawl/crawldb $s3

確認。

$ bin/nutch readdb crawl/crawldb -stats
CrawlDb statistics start: crawl/crawldb
Statistics for CrawlDb: crawl/crawldb
TOTAL urls:	28124
retry 0:	28083
retry 1:	41
min score:	0.0
avg score:	0.054256257
max score:	4.324
status 1 (db_unfetched):	25426
status 2 (db_fetched):	2391
status 3 (db_gone):	104
status 4 (db_redir_temp):	78
status 5 (db_redir_perm):	125
CrawlDb statistics: done

最後に invertlinks コマンドで linkdb を生成する。

$ bin/nutch invertlinks crawl/linkdb -dir crawl/segments

linkdb はそれぞれの URL がどのページからリンクされているかという情報をもっている。readlinkdb コマンドで dump を見ると、以下のような内容になっている。

$ bin/nutch readlinkdb crawl/linkdb -dump out_dir
$ less out_dir/part-00000
http://12fret.com/feed/ Inlinks:
 fromUrl: http://www.12fret.com/ anchor: RSS Feed

http://137.69.120.115:8080/xformsdemo/  Inlinks:
 fromUrl: http://www.w3.org/MarkUp/Forms/ anchor: Online demo

http://1800gotjunk.com/ Inlinks:
 fromUrl: http://www.esplanade-juanita.com/links.php anchor: 1800-GotJunk

http://1und1.de/        Inlinks:
 fromUrl: http://www.wahrenburg-reisen.de/stellenangebote/ anchor: 1&1
 fromUrl: http://www.wahrenburg-reisen.de/über-uns/ anchor: 1&1
 fromUrl: http://www.wahrenburg-reisen.de/ anchor: 1&1
 fromUrl: http://www.wahrenburg-reisen.de/kontakt/ anchor: 1&1
 fromUrl: http://www.mvlyra.de/ anchor: 1&1
 fromUrl: http://www.wahrenburg-reisen.de/reisen/ anchor: 1&1
 fromUrl: http://www.mvlyra.de/gästebuch/ anchor: 1&1
 fromUrl: http://wahrenburg-reisen.de/sitemap/ anchor: 1&1
 fromUrl: http://www.mvlyra.de/termine/ anchor: 1&1
 fromUrl: http://www.wahrenburg-reisen.de/fahrplanauskunft/ anchor: 1&1
 fromUrl: http://www.wahrenburg-reisen.de/impressum/ anchor: 1&1
 fromUrl: http://www.mvlyra.de/kontaktaufnahme/ anchor: 1&1

ここまでで、Solr にプッシュするためのデータソースを作成することができた。

4. Solr のインストール

Nutch でクロールが完了したら、検索インデックスを生成するために Solr をセットアップする。まずは Solr 4.0 のダウンロード。

$ cd ~/src
$ wget http://mirrors.ibiblio.org/apache/lucene/solr/4.0.0-ALPHA/apache-solr-4.0.0-ALPHA.tgz
$ cd
$ tar zxvf ~/src/apache-solr-4.0.0-ALPHA.tgz
$ mv apache-solr-4.0.0-ALPHA/ solr-4.0

5. Solr の設定・起動

Nutch のパッケージに同梱されている schema.xml をコピーする。

$ cd solr-4.0; cp -rp example dmoz-example
$ cd ~/nutch-1.5/example/
$ cp -r conf/schema-solr4.xml ~/solr-4.0/dmoz/solr/conf/schema.xml

Solr 起動。

$ cd ~/solr-4.0/dmoz-example
$ java -jar start.jar

※ Solr 4.0 の 設定ファイル群と Nutch に同梱されている schema.xml の内容に一部ズレがあり、起動時に設定ファイルの参照エラーになったため、応急処置的に設定ファイルを追加した。

$ cp -p conf/stopwords.txt conf/stopwords_en.txt

6. Nutch の SolrIndexer を起動

Solr の準備が整ったら、Nutch の solrindexer を起動する。

$ cd ~/nutch-1.5/dmoz-example
$ bin/nutch solrindex http://127.0.0.1:8983/solr/ crawl/crawldb -linkdb crawl/linkdb crawl/segments/*

ブラウザから結果を確認。

http://127.0.0.1:8983/solr/

これで、DMOZ データベースのインデックス作成と検索までできるようになった。Nutch は nutch-site.xml の設定パラメータを変更することでクローラーのパフォーマンスがかなり変わってくるので、使っている環境にあわせて試して見ると面白い。とりあえずこんなところで。