2007年11月06日

なんか男前そうなクロウラーたんを発見したお

資料はhttp://www.slideshare.net/lestrrat/gungho-swarmage-pocomdba/を見るべし。

ちなみに、これ書くのに使ったGunghoはVersion 0.09001 のCPANの。

概要

GunghoはPlaggerっぽいwebクロウラーたんです。なのでGunghoの名前空間以下にあるモジュールとかを個別に使おうとしたら大変です。
Gunghoのアーキテクチャにそった一本道な動作をさせるのがいいはず。
設定はConfig::Any使ってるので、色んな形式のを使えます。

Providerにより収集URLを取得し、EngineがHTTPでコンテンツを取得し、Handlerで取得したコンテンツを処理します。 Provider,Engine,Handlerは、それぞれ一つづつしか選べません。
まぁよくあるとおり、Gungho::Component以下のにあるやつとか+つきのcomponentを自由にGunghoに継承させれます。Pluginってのも追加出来ます。
おまけにLogってのも選べます。

Engine

EngineにはPOE,brad,IO::Asyncが選べます。どれも非同期なやつですね。
EngineはGunghoからrunメソッドにcontextを引数として起動されます。そのまえにsetup処理も入るけど。
とにかくrunから先はengineさんの好きにしても良いです。
でもやんなきゃいけない事は、runされたらcontextのdispatch_requestsを呼び出して下さい。 これはGungho::Component::Coreに居ます。

何をするかと言うとProviderのdispatchメソッドさんを呼び出します。
こいつが、URLをGungho::Requestにラッピングされてるオブジェクトを延々とcontextのsend?requestメソッドに投げます。
そしてPluginとかでdispatch.dispatch_requestsフックの処理とかをして、engineのsend_requestに送ります。
engineのsend_requestはローカルアドレスとかDNSがあるかとかを見てくれてます。

そしてengineのsrart_requestメソッドを呼び出します。
これは、まさしくhttpつかってコンテンツを取得する所です。
エラーがあるか、正常にコンテンツが取れるかに関わらず、engineのhandle_responseメソッドが呼ばれ、Gungho::Responseのオブジェクトとしてレスポンスをラッピングしてからcontextのhandle_responseメソッドを呼びます。
ちなみにbradとIO::AsyncはHTTPをGunghoが喋っていて(Gungho::Request::httpでrequest作成)HTTP::Parserで処理されたのをGungho::Responseに渡してる。

で、Coreのhandle_responseが呼ばれたら、とりあえずnextしてみてから、Handlerのhandlerメソッドに処理を投げます。
あとは、Handlerたんの実装しだいで好きにしてね。

なんか良くわからないけど、engineによって呼ばないhookがある。
あとあと、なんでdmaki wareなのにGungho::Handler::Swarmageがないのかが謎。

IO::Asyncつかうと何かエラーでた。

Cannot operate on a notifer that is not read-bound to a handle with a fileno at /usr/lib/perl5/site_perl/5.8.5/Gungho/Engine/IO/Async.pm line 138

Danga::Socketはなんあか起動に時間かかり過ぎで家の環境だとうまくいってなす。たぶん家のDNSのせいっぽいけど。結局POEか。

Provider

処理するリクエストを扱ってくれるマシン。
dispatchが呼ばれたらcontextのdispatch_requestメソッドにGungho::Requestなオブジェクトを投げ続けます。
engine君はループで延々とdispatchを呼んでくるので、辞めたくなったらcontextのis_runnningに0をあげるとengine君は止まります。

pushback_requestがたまに呼ばれます。
なんらかの事情によりリクエストを最初からやり直したい時とかに、やり直したいリクエストが渡されるので、各Providerでリクエストプールかなんかに戻してあげて、dispatchが呼ばれた時に、それをまた投げてあげて下さい。
POE使ってる時はタイミングによってはis_runningが0になっちゃってリクエストが処理されない気がするけど泣いちゃ駄目。確かにPOEでRobotRules使うとタイミング次第でだめぽ。

Handler

このくらいはソース読め

面白いComponent達の挙動

RobotRules

robots.txtを持ってなければ、requestをpendingリストに突っ込みrobots.txtを取って来るrequestをpushbackする。
robots.txtを取れた時にpendingリストに入れられたrequest全てをpushbackする。
storageにmemcachedとか使えるけど、いづれにしろ非同期。

で、うごかねーーとか思ってたら、Gunghoのtestが/tmp/robots.dbにテストファイルおきっぱなしで消してなかったorz

BlockPrivateIP

Danga::SocketかIO::Asyncをengineしてる時に、これ使ってないと血を吐いて死ぬ。

Authentication

認証付きのURLをクロールするには必須。

Throttle::Domain

Data::Throttlerというモジュールを使って、一つのドメインに対するリクエストを特定期間の間に特定回数しか行わないようにできる。
なので、例えば1時間のうち100回までしかアクセスしない。と設定してもGunghoは一気にリクエストがきたら1秒間に100回アクセスする。
十数秒/1回がベターか?それかネスト出来ると良いかもね。
なにはともあれData::Throttlerってモジュールが面白いよ!

どっちかって言うとAレコード版も欲しいってか簡単だから作ろうかな

Componentで使えるメソッド達

基本Gungho::Component::Core見ろ。

setup

初期化フェーズ。初期化したければここかいてnextれ。

send_request

リクエスト前になんかやる。RobotRurles見ろ。

handle_response

リクエスト後になんかやる。RobotRurles,RobotsMETA見ろ。

hook points

たぶん色々変わりそうだから略

Posted by Yappo at 2007年11月06日 23:42 | TrackBack | Perl
Comments
Post a comment









Remember personal info?






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