ウェブ自動巡回ボット-bot-の作り方 for Perl 初級編

 そういえば昔はてなの人力検索で、アンケートにbotで自動回答してる奴がいるとか居ないとかで話題になったことがあったのを思い出して書いてみた。はてなアイデアにも一連の関連アイデアが出ている。
はてなアイデア
 そもそも1回答当たり1ptというインセンティブの低さとか、匿名回答者の質の低さとかそういう問題が主である気もするが、これ以降はbotの問題に限って言うと、CAPTCHAみたいな逆チューリングテストの導入は、結局アクセシビリティとトレードオフ。インセンティブが変わらず作業量だけ増えてめんどくさくなり、かなり回答率が下がると思われるので多分逆効果だろう。
 わざわざチューリングテストをかまさなくても、選択肢のラジオボタンの部分をJavascript(欲を言えばFlash)にするだけで、かなりbotの回答を回避できると思うのだが。少なくともHTMLをparseして解析結果を元にrequestを返すタイプのbotは完全にシャットアウトできる。


 まあとにかく、人力検索のアンケートに自動投票させるbotなんてものは、多少Perlをいじったことのある人なら簡単に作れてしまうのだ。UserAgentを偽装して、アクセス日時を有機的にすれば、そう簡単にはバレはしないだろうし(もちろん僕はそんなことはしないが)。
 ほーらbot作成ってこんなに簡単だよ〜ということをみんなに知ってもらうことで、セキュリティ対策の啓蒙とか違法なbotへの対策を促す事に繋がればいいなあということで、bot作成講座を書いてみる。C++.NETとか使えばもっとレベルの高いbot(画面のピクセル単位でクリックを管理できるようなやつ)が作れるんだろうけど、ここでは簡便性と実用性を重視してActivePerlを使う。bot作成講座はとりあえず全3〜4回を予定していて、作り方も使い方も徐々にえげつないものになる予定。

botで出来ること

・日常的に使う会員制サイトの自動ログイン

 人によっては、かなり時間短縮になる。個人用パソコンであればブックマークレットのほうが簡単で実用的だが、ショルダーサーフィン(パソコンの画面を後ろから覗き込まれる)のリスクが心配な人は、Perlでログインスクリプトを作ってパスワードをかけておけばよいだろう。自作OpenID的なものだと思っていただければ。

・情報サイトから特定の情報を定期的に抜き出して表示

 Yahoo! PipesライクなRSSフィードの収集と再構築ができる。しかもRSSじゃなくてもOK、特定のidを持つdivタグ内を取得みたいなことが可能。あと、Windowsのタスク管理とかUNIXのcronと組み合わせて、定期的に時間指定でコンテンツを抜き出すことも可能。ただし、ウェブで公開する場合は収集先の著作権とかに注意。

・URL、メアドの収集、収集したURLの特定のコンテンツを収集

 Google等のサーチエンジンが使ってるbotとほぼ同じ用途。これも小規模であれば意外と簡単。スパマーはこの方法でメアドを収集して、メール一斉送信スクリプト(これも簡単に作れる)で無差別送信していると予想される。この辺りのロジックを具体的に知っておくことで、意外なスパム対策を思いつくことができるかもしれない。

・受信したメールから抽出したURLにアクセス

 応用。Net::POP3などのモジュールでメールを受信し、そこからURL等を抽出してそのページに自動アクセスする。イマイチ利用法が思いつかないが、メールと連動できるのを知っておくといろいろ使い道があるかも。

botでは出来ないこと

・MMORPGのチート
・クリックインセンティブ系サイトの自動巡回

 FlashやJavaなどを使用しているサイトは、今回説明する方法では操作できない。また、「クリックすればお金がもらえる」的なサイトは大抵Javascript等でbot対策が成されているので、これも不可。規約違反だろうし。

用意するもの

・Windows XPの入ったパソコン

 ビッグカメラとかでWindowsの入ったパソコンを(ry

・ActivePerl 5.8.8

 WindowsではPerlがデフォルトで動かせないのでActivePerlというPerlインタプリタ(Perlで書いたプログラムを動かすソフトみたいなもん)を導入する。インストール方法については下記のサイト参照

 ActivePerlのインストール方法 - Windowsでperlを使おう!

 ActivePerlをインストールすると、拡張子.plのファイルがActivePerlのアイコンになり、ダブルクリックするとPerlスクリプトとして実行できるようになる(ActivePerlのアイコンにならない時は、エクスプローラのフォルダオプションで関連付けてください)。ただ、この方法だとプログラムの実行が終了した時点でウインドウが閉じてしまうので、じっくり処理結果を見たいときは最後にsleep(10);などを書き加える必要がある。これで処理終了後も10秒間ウィンドウが保持されるようになる。
 txtファイルでスクリプトを書き、完成したら拡張子をplに書き換えて実行(もしくは拡張子.plのファイルとして作成し、右クリック→[プログラムから開く]からエディタで編集)といった感じ。もちろん、CGIじゃないので#!user/bin/local/perlは不要。

・CPANモジュール

 CPANとはPerl用の公開モジュールライブラリであり、おそらくPerlを使うほとんどの人がPerlを使い続ける最大の理由。Perlでbot作成が簡単なのは、bot作成に便利なフリーのモジュールが豊富にそろっているから。


チュートリアル:情報収集スクリプト - 「はてなアンテナもどき」


 初級編では、「はてなアンテナもどき」をつくる。登録したURLのHTMLを取得して、ローカルに保存してある過去のHTMLと食い違っていたら更新を知らせる。シンプルだが、正規表現と組み合わせることにより、株価とか為替レート取得して解析したり、RSS配信してないニュースサイトから特定のワードを含む記事だけ抜き出したりするなど、幅広く応用が可能。作成したbotの使用については自己責任で。

LWP::Simpleモジュールのインストール

 今回は、LWP::Simpleというモジュールを使用する。これは最近のActivePerlにはデフォルトで含まれているようなので、use LWP::Simple;と書いてエラーが出なければOK。エラーが出たらインストールする(ActivePerl付属のPerl Package Managerから簡単にインストールできる)。LWP::Simpleについては下記サイト参照
 LWP::Simple - simple procedural interface to LWP - metacpan.org

 LWP::Simpleの使い方はいたってシンプル。

use strict;
use Encode;
use LWP::Simple;

my $content = get("http://d.hatena.ne.jp/heilig_zwei/");

#DOSプロンプトが化けるのでshift-jisに変換
Encode::from_to($content, "euc-jp", "shift-jis");

print $content;

 これだけでOK。getで指定したサイトのURL(例では当サイト)からHTMLを拾ってきて、printで表示する。LWP::Simpleで使うメソッドは基本的にgetのみなので、定型として覚えたらいいと思う。次に、「登録したURLのHTMLを取得して、ローカルに保存してある過去のHTMLと食い違っていたら更新を知らせる」機能を実装する。


※どうもエンコード関係が苦手なので、下のスクリプトはshift-jisで書いてます。

use strict;
use Encode;
use LWP::Simple;

my $content = get("http://d.hatena.ne.jp/heilig_zwei/");

#ローカルに保存した過去のHTML情報を開く
open(IN,"<log.txt") || die "Open Error : log.txt\n";
my $old_page;
foreach (<IN>){
	$old_page .= "$_";
}
close(IN);

#新しく取得したものと照合
if ($old_page eq $content){
	print "\更新はありません。\n";
}else{
	open(IN,">log.txt") || die "Open Error : log.txt\n";
	print IN $content;
	close(IN);
	print "\更新がありました。\n";
}
sleep(2);

 以上。スクリプトを実行すると、「更新がありました。」「更新はありません。」のいずれかが表示される。ちなみにGoogle Adsenseみたいな動的コンテンツを入れると、アクセスするたびに更新があったと判断されるため、これ単独では実用性は皆無。ただ、先ほども述べたように、LWP::Simpleは正規表現と組み合わせることで非常に楽しくなるので、色々試してほしい。そういえばajaxのクロスドメイン制約を解消する時にもLWP::Simpleは使った気がするな。


 次回は、URLを自動収集したり、ログインフォームを送信してブログの自動書き込みしたり、もう少しbotっぽいものになる予定。

↓次記事(5/3更新)
Bot作成講座2 - Perlでさくっとスパムブログを作ってみる - 後ろを見ろ、後ろを!

参考図書

Spidering hacks―ウェブ情報ラクラク取得テクニック101選

Spidering hacks―ウェブ情報ラクラク取得テクニック101選