2008年2月27日水曜日

2chのスレを自動保存

2chのスレを自動で保存する方法を考えます。
スレの進行が早いところはすぐにDAT落ちしてしまいます。プログラムによって定期的にDATを取得できたら便利です。
いきいきwikiによるとUser-AgentをMonazilla/1.00 (ブラウザ名/バージョン)にするといいようです。
また鯖の転送量を減らす目的でgzipを推奨しています。
例としてJaneviewのリクエストヘッダを見て見ます。


こんな感じです。
これよりどこにアクセスし、DATを取得しているか分かります。
取得したdatはgzipに圧縮されているのでgunzipで展開します。(gunzipコマンドのあるLinux環境を想定しています)
ここで注意して欲しいのは必ずgzipで返ってくるとは限らない点です。gzipではなく生のDATが送られてきても対応できるようにします。

例としてDATを取得するスクリプトをいかに示します。定期的に取得する場合はcronなどで回して下さい。

#!/usr/bin/perl
use Net::HTTP;

### Initial Setting ###########################

$server ="namidame.2ch.net";
$category ="campus";
$unixtime ="1234567890";
$backup_directory ='/var/www/';

###############################################

unless($backup_directory=~/\/$/){
$backup_directory.='/';
}


$s = Net::HTTP->new(Host => "$server") || die $@;
$s->max_line_length(0);
$s->keep_alive(300);

$s->write_request(GET => "/$category/dat/$unixtime.dat", 'User-Agent' => "Monazilla/1.00 (perl/1.3)" , 'Accept-Encoding' => "gzip" );


($code, $mess, %h) = $s->read_response_headers;
unless($code eq "200"){
print "Thread not found!\n";
exit;
}

open (FH,">$backup_directory$unixtime.dat.gz") or die $!;

while (1) {
my $buf;
my $n = $s->read_entity_body($buf, 1024);
die "read failed: $!" unless defined $n;
last unless $n;
print FH $buf;
}

close FH;


print "\n$code $mess\n";
foreach $key(keys %h){

print $key," ";
print $h{$key},"\n";

}


chdir "$backup_directory" or die $!;
$gunzip_message = qx/gunzip -f $unixtime.dat.gz 2>&1/;

if($gunzip_message=~/not.*in.*gzip.*format/){
exec "mv $unixtime.dat.gz $unixtime.dat";
}

0 件のコメント: