2005年08月06日

Xango

XangoはPerlで書かれた汎用クローラーフレームワークです。
イベント型フレームワークPOEを使用することにより高速なクローリングが可能です。
実装にもよりますが、単一プロセス内でインデックシングや文字コードの変換等の処理を
同時に行うアプリケーションでも1秒に5~8 URL、1時間で 18000 ~ 22000 URLの処理が行えます。

ドキュメントはperldocのみっぽいので、日本語の情報を残す意味で使い方のメモをば。
相当端折って書いてます。

Xangoを使ったクロウラーを書くには、制御用のにPOEセッションを作る必要があります。
Xangoを制御するためのモジュールを適当な名前で作っておくのがスマートかと思います。

とりあえずセッション作成を行う処理を書きます


sub spawn
{
my $class = shift;
my %args = @_;
my %heap = (
);
POE::Session->create(
heap => \%heap,
package_states => [
$class => [
qw(_start _stop),
qw(retrieve_jobs apply_policy prep_request),
qw(handle_response finalize_job),
]
]
);
}

こんな感じです。

次にAliasの設定です。ユーザー側のセッション名はhandlerをつけると事になっているので、Aliasをこれに設定しておきます。


sub _start
{
my($kernel) = @_[KERNEL];
$kernel->alias_set('handler');
}

sub _stop
{
my($kernel) = @_[KERNEL];
$kernel->alias_remove('handler');
}

次は、URLリストの取出しです。
XangoがURLリストの取得が必要だと判断した時にretrieve_jobs()を呼び出しますので、URLのリストを返します。
訪問先URLリストが無ければundefを戻せばおk


sub retrieve_jobs
{
print "retrieve_jobs: $count\n";
$count++;
#return undef;
return ({
uri => 'http://example.jp/',
my_var => $count,
my_other_var => $count,
},{
uri => 'http://2.example.jp/',
my_var => $count,
my_other_var => $count,
}
);
}

ハッシュリファレンスの配列として戻します。
my_varやmy_other_varのように、ユーザー側独自の値も設定できます。
こお処理はDBからURLを引っ張ってくるとかそんな事をします。


次に、Xangoが訪問先のURLにアクセスを行うべきかを問い合わせます。
robots.txtに基づくアクセス制御や、同一ホストに連続でアクセスすることを防止する処理を書く感じです。


sub apply_policy
{
my($kernel, $job) = @_[KERNEL, ARG0];

#$job->{uri}

#$kernel->post('broker', 'finalize_job', $job); #deny
$kernel->post('broker', 'send_fetcher', $job); #any
}


$job->{uri}にURLが入っています。
okならsend_fetcherを、だめならfinalize_jobを呼び出します。
この処理を忘れると正常に動きません。


次に、HTTPリクエストを実行する直前に呼ばれる処理です。


sub prep_request
{
my($kernel, $job, $req) = @_[KERNEL, ARG0, ARG1];
}

$reqHTTP::Requestのオブジェクトになっています。


いよいよ、取得したデータを処理するフェーズです。


sub handle_response
{
my($kernel, $job) = @_[KERNEL, ARG0];
#$job->{http_response}
# $kernel->post('broker', 'finalize_job', $job);
}

$job->{http_response}HTTP::Responseオブジェクトになっています。
もし、Xangoの挙動がおかしいときはfinalize_jobを呼び出してみてください。
svnバージョンだと必要でした。

最後に、HTTPリクエストの後処理です。必要だったら書いてください。


sub finalize_job
{
my($kernel, $job) = @_[KERNEL, ARG0];
}

オマケとして、設定ファイル処理中にXangoから呼び出しがあります。


sub load_config
{
my($kernel, $config_filepath) = @_[KERNEL, ARG0];
}

$config_filepathは、そのまま設定ファイルのパスが入ります。
で、その設定ファイルですがYAML形式で記述をします。
詳細はperldocを見てください。
HttpComponentArgsに、POE::Component::Client::HTTPに渡す初期設定を記入できますので
UAを独自の物にしておくと良いでしょう。

HttpComponentArgs:
Agent: Xango/test
MyConfigParam: hoge

MyConfigParamの様な独自設定も記入できます。
解析は先ほどのload_configで行います。

最後に実行するスクリプトです。


use strict;
use Xango;
use Xango::Broker;
use MyHandler;

MyHandler->spawn();
Xango::Broker->spawn(conf => './conf');
POE::Kernel->run();

と、こんな感じでXangoを使うことが出来ました。
昔のバージョンだとリンク解析とかEncodeとかrobots.txtとか色々面倒見てくれた気もするけど
現在は、貰ったURLリストをPOEらしくパラレルで高速に巡回する事に徹したフレームワークになっています。(DNSキャッシュを内部で行っているというのもいい感じです。)
その分、サーバ毎のアクセス間隔やrobots.txtへの準拠はキッチリと書かないといけないですが。

POEを使ったクロウラーたんを書きたい時には重宝しそうです。
あとはXangoX::* or Xango::Ex::* なモジュールが増える事に期待。


一応、今回のファイルもあげておくテスト。
MyHandler.pm
test.pl
conf

MFPM::Xango

Posted by Yappo at 2005年08月06日 15:43 | TrackBack | Perl
Comments

私もSennaとの組み合わせで使いたくて、Xangoを調べています。

何故か、Yappoさんの書いたXango使ったクロウラーのソースコードファイルがリンク切れで取得できません。残念。

ところで、オープンソースで今、一番お勧めのクローラーって何でしょうか?

たくさんあるけど、いったいどれが良いのか。。。

そもそも、検索エンジンの類って、対象技術を知っている人がすごく少ないし。

Yappoさんは最先端ですね!

Posted by: Xangoビギナー at 2005年08月16日 17:39

訂正です。
サンプルソース、取れました。

何故か、コメントポストしたらリンク先にアクセスできるようになりました。


ブラウザがおかしいのかな。

Posted by: Xangoビギナー at 2005年08月16日 17:43

たまたまPOEでクロウラーを作る需要があったのでXangoを見てみた感じなのです。
クロウラー回りは案件ごとに実装したい内容がだいぶ変わるから
できもののを使うよりかは独自で書いたほうがよい感じです。
Xangoくらいのフレームワークを使いつつ書くのがちょうどよさそうです。

有りもの使うんならwgetとかでもよさそうです

Posted by: Yappo at 2005年08月18日 20:37

Yappoさん、コメント返しありがとうございます。

YappoさんのサンプルをベースにXangoの動作確認をしてみました。

一部の関連するCPANモジュールのインストールで梃子摺りましたが、何とか動作させられました。

Xangoってフレームワークというだけあって、ビルトインで使えるというわけではなく、大部分の処理を自分で書かなければいけないんですね。

その分、自由度が高いわけですが。
使い込んで慣れていけば、一番よさそうかも。

でも、手っ取り早くクローラーを用意するならwgetなんでしょうかね。。。


Posted by: Xangoビギナー at 2005年08月19日 20:33
Post a comment









Remember personal info?






コメントを投稿する前に↓の場所にnospamと入力してください。