すでに誰かが絶対に書いているはずとは思ったのですが、 探すよりも書いた方が早そうだったので、 livedoor ブログの生ログを取得する perl スクリプトを 書いてみました。 ついでに、デザインをカスタマイズしたときの、 スタイルシート(CSS)やHTMLのテンプレートも取得できます。 例えば、
livedoor.pl gcd raw_log 10 log.csv
などと実行すれば、10 ページ分 (200行) の生ログを、 CSV 形式でファイル「log.csv」に保存できます。 また、
livedoor.pl gcd index_tmpl index.html
などと実行すれば、インデックスページのHTMLテンプレートを、 ファイル「index.html」に保存できます。 第一引数「gcd」の部分には、 ブログのアカウント名 (スクリプトの先頭部分で定義しています) を 指定してください。 私の場合、 「GCD 日記」と 「仙石浩明CTO の日記」の 二つのブログアカウントがあるので、 それぞれ「gcd」と「klab」という名前で定義しています。
余談ですが、二つのブログを書いているのは、 個人用と会社用とを区別しようというわけではありません。 もともと私のなかでは趣味と仕事の境界線が曖昧なので、 個人と会社でブログを区別しようとしても混ざってしまうでしょうから、 区別することに意味があるとは思えません。 じゃ、なぜ二つのブログなのかと言えば、 「GCD 日記」のほうが よりメモ的でネタを蓄えておき、ある程度考えがまとまったものを 「仙石浩明CTO の日記」へ 書こう、というのが そもそもの意図でした。
やっつけ仕事なので、突っ込みどころ満載(^^;) のスクリプトだとは思いますが、 livedoorブログをお使いの方はご利用頂ければ幸いです。 もちろん、ご利用の際は先頭部分のユーザID & パスワード等を 適宜修正してください。 また、スクリプト中で日本語を使っているので、 このスクリプトは EUC-JP で保存する必要があります。
livedoor.pl (livedoor blog 生ログ & CSS/テンプレート 取得スクリプト)
#!/usr/bin/perl
use LWP::UserAgent;
use HTTP::Request::Common;
use CGI qw/unescapeHTML/;
%blogs = (
"gcd" => {
"User" => "hiroaki_sengoku",
"Pass" => "xxxxxxxx",
"BlogID" => 1600549,
"ID" => 11111,
"PageID" => 22222,
},
"klab" => {
"User" => "klab_sengoku",
"Pass" => "yyyyyyyy",
"BlogID" => 1631449,
"ID" => 33333,
"PageID" => 44444,
},
);
&help unless $_ = shift;
if (my $blog = $blogs{$_}) {
$User = $$blog{"User"};
$Pass = $$blog{"Pass"};
$BlogID = $$blog{"BlogID"};
$ID = $$blog{"ID"};
$PageID = $$blog{"PageID"};
} else {
&help;
}
$ua = new LWP::UserAgent;
$ua->agent("Mozilla/5.0 (Windows; U; Windows NT 5.1; ja)");
$ua->env_proxy();
$ua->cookie_jar( {} );
my $res = $ua->request(POST "http://member.livedoor.com/login/index",
[ "livedoor_id" => $User, "PASSWORD" => $Pass,
".next" => "", ".sv" => "" ]);
while (my $type = shift) {
if ($type eq "css" || $type eq "index_tmpl" || $type eq "article_tmpl" ||
$type eq "category_tmpl" || $type eq "monthly_tmpl") {
my $file = shift;
open(OUT, ">$file") || die;
my $url = "http://cms.blog.livedoor.com/cms/design/edit"
. "?tmpl=$type&blog_id=$BlogID&id=$ID";
my $req = new HTTP::Request GET => $url;
my $res = $ua->request($req);
if ($res->content =~
/\<textarea .*name=\"content\" [^\>]*\>([^\<]+)\<\/textarea\>/) {
my $content = unescapeHTML($1);
$content =~ s/\r\n/\n/g;
print OUT $content, "\n";
}
close(OUT);
} elsif ($type eq "raw_log") {
my $npage = shift;
($npage =~ m/^\d+$/ && $npage >= 1) || &help;
my $file = shift;
open(OUT, ">$file") || die;
my $url = "http://analyzer.livedoor.com/log/raw?page_id=$PageID";
my $prepat = '\<td\b[^\>]*\>\<strong\>\<small\>';
my $postpat = '\<\/small\>\<\/strong\>\<\/td\b[^\>]*\>';
for (my $i=1; $i <= $npage; $i++) {
my $req = new HTTP::Request GET => "$url&p=$i";
my $res = $ua->request($req);
my $datepat = '\d\d\d\d\-\d\d\-\d\d \d\d\:\d\d\:\d\d';
my $date;
for (split(/(\<small\>$datepat\<\/small\>)/, $res->content)) {
if (/^\<small\>($datepat)\<\/small\>$/) {
$date = $1;
} elsif (/^\<\/th\>\s*\<\/tr\>\s*/) {
my @record;
for (split(/\<\/tr\>\s*/, $')) {
my $column;
if (/$prepat(.*)$postpat/o) {
if ($1 eq 'URL') {
$column = 0;
} elsif ($1 eq 'リファラ') {
$column = 1;
} elsif ($1 eq 'ブラウザ') {
$column = 2;
} elsif ($1 eq 'リモートホスト') {
$column = 3;
} else {
die "Unknown column: $_\n";
}
}
if (/\<td\b[^\>]*\>\<small\>(.*)\<\/small\>\<\/td\b[^\>]*\>/){
$_ = $1;
s/\<\/?a\b[^\>]*\>//g;
if (/,/) {
s/\"/\"\"/g;
$_ = "\"$_\"";
}
$record[$column] = $_;
} elsif (/^\<\/table\>/) {
last;
} elsif (! /^\<tr\>\s*\<th\b[^\>]*\>/) {
die "Unknown format: $_\n";
}
}
print OUT $date, ",", join(',', @record), "\r\n";
}
}
}
close(OUT);
} else {
&help;
}
}
exit 0;
sub help {
print "Usage livedoor <blog> <opt>...\nblog: ",
join("\n ", keys %blogs), "\n",
'opt: css <file>
index_tmpl <file>
article_tmpl <file>
category_tmpl <file>
monthly_tmpl <file>
raw_log <n> <file>
';
exit 1;
}