mixiで自動的に他人へ足跡を付けて回りたい

Counter
ということで,パソコンをずっとつけっぱなしにしている状態で,人の手を使わずに,簡単なスクリプトで他人に足跡を付けて回る方法を考えてみる。 なんで,そんなことをするかっていうのは,この際おいておく。悪いことに使わないように。あとは,パラメータをいじって効率アクセスしすぎると,mixiの運営会社からマークされてしまうので程々に。
さて,mixiのアクセスはすべてウェブブラウザー経由だ。ということは,所詮HTTPというテキストベースのプロトコルのやりとりである。ということは,人がブラウザーを操作するときに,どんな通信が行われているかを調べ,その挙動をスクリプトで再現してやればよい。もっと言うならば,同じ原理で,足跡を付けて回る,という一番単純な操作だけでなく,自動的に他人へmixiメールを送るとか,マイミクの申請を送るとかもできてしまうわけだ。

最初に,調査が必要である。ということで,以降では調査を行っていく。


まず,mixiにはログインが必要である。そして,一度ログインすれば認証無く足跡を付けて回ることができる。この仕組みはどうなっているのだろうか。これはcookie というものを使っているようである。つまり,ブラウザでログインし,そのcookie を手に入れれば,そのcookieを使って「ブラウザで操作したのと同じように」ログインされた状態での操作が行われるわけだ。
その方法は,実に簡単である。
1. mixiに普通にログインする。 2. その画面のアドレスに http://mixi.jp/ 等の代わりに
 「javascript:document.cookie
 と打ち込む。
3. そこで表示された文字を記録しておく
ここで,BF_SESSION=xxxx; BF_STAMP=xxxx; BF_SETTING=xxxx; rsi_ct=xxxx; IMPASEG=xxx というような文字が出てきたら成功である。
次に,他人に足跡を付けるにはどうしたらいいのだろうか。それは,非常に簡単で,まずブラウザで友人のページを表示してみる。そのときのアドレスを見てみると,
http://mixi.jp/show_friend.pl?id=12345xxx
となっている。さらにもう一人見ていくと,ルールが見えてくる。どうやら 「http://mixi.jp/show_friend.pl?id=」 のあとに個人の番号として数字が並んであるようである。しかも,リンクをたどらずとも,直接ブラウザにこのような文字を打ち込んでも正しく表示できるようである。つまり,別にややこしいデータを送る必要はなく,単純にブラウザでそのURLにアクセスするだけで済むということである。もう少し技術的な言い方をすると「GET」という単純なメソッドでアクセスすればよいようである。
最後に,ツールを探してみよう。Webに簡単にアクセスできるスクリプト言語は,VBA,perl,php,rubyなどがあるようだが,昔からwindowsで使われているperlを選ぶことにする。http://www.activestate.com/ から無料でバイナリをダウンロードすることができる。ここから,英語だがマニュアルを見ていくと,「LWP::UserAgent」というモジュールが今回の目的に適していそうだ。使いそうな関数を挙げていく。
agent : ユーザーエージェント,つまりブラウザの種類を示す。IEの真似をしたい。
header : ヘッダを指定する。cookieやrefererを指定できる。
request : 実際にアクセスする。
この辺りだけで済みそうだ。

次に実際にアクセスするにはどうしたらよいか


まずは,ボトムアップ的に,アクセスする関数を作ってみる。
#!/usr/bin/perl
use LWP::UserAgent;

#cookieをブラウザからコピーする
$cookie="BF_SESSION=xxxx; BF_STAMP=xxxx";

# 呼び出し口
sub myWebAccess
{
	my ($url, $ref)=@_;

	my $uaa = new LWP::UserAgent;
	# ブラウザのタイプを指定。InternetExplorerの真似。
	$uaa->agent('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)');
	
	# アクセスするURLを登録
	my $req = new HTTP::Request GET => $url;
	# ブラウザからアクセスしたようにヘッダを追加
	$req->header(Accept => "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*");
	$req->header("Accept-Language" => "ja");
	# ちゃんとリンクをたどってきたように見せる
	$req->header("Referer" => $ref);
	$req->header("Connection" => "Keep-Alive");
	# ログイン状態でアクセスするためにcookieもつける
	$req->header("Cookie" => $cookie);
	# さてアクセスだ
	my $res = $uaa->request($req);

	if ($res->is_success) {
		# アクセスに成功したら
		print STDERR "len=".length($res->content)."";
	}else{
		# アクセスに失敗したら
		print STDERR "None";
	}
}
このうち,初めの $cookie= の行をそれぞれのアカウントにあわせて,ブラウザに表示された内容に置き換える。 そうすれば,この関数を呼び出せば自分の代わりにアクセスしてくれると言うことだ。
myWebAccess('http://mixi.jp/show_friend.pl?id=12345xxx','http://mixi.jp/home.pl');
という具合に。
次は,この関数を使って,足跡を付けることを全部スクリプトに任せてみる。 決まったお友達に,「たまには訪れてますよ」という形でアピールしたい場合には次のようにすればよい。id= 以降のリストが決まっていたら,foreach 文で回してやればよい。
@mylist=( 3234,53235, 4234324,32344);
foreach $myitem (@mylist){
	$myurl='http://mixi.jp/show_friend.pl?id='.$myitem;
	$myref='http://mixi.jp/home.pl';
	myWebAccess($myurl,$myref);
	$num=int(rand(150*2))+100;
	print STDERR "sleep $num sec, ";
	sleep($num);
}
@mylist というのが訪問するマイミクの番号である。一度は訪問し,そのときのアドレスに表示されるURLの id=以降の数字をあらかじめ控えておく。もう一つ重要なのは,ちゃんと間隔を空けること。人がやったように,ある程度最低限の時間をおいて,また定期的ではなく,感覚に揺らぎを持たせるように sleep コマンドで待たせている。上記の例の場合,100秒は必ず待ち,平均 150秒(0秒から300秒)を追加するということである。
最後に,お友達を新規開拓したい場合には,ランダムでidの番号を発生させると良い。
while(true){
	$myitem=int(rand(100000));
	$myurl='http://mixi.jp/show_friend.pl?id='.$myitem;
	$myref='http://mixi.jp/home.pl';
	myWebAccess($myurl,$myref);
	$num=int(rand(150*2))+100;
	print STDERR "sleep $num sec, ";
	sleep($num);
}
おしまい。