昨日書いた「livedoor blog 生ログ取得スクリプト」を使って、
毎日前日の生ログを取得する cron を仕掛けておいたのですが、
月が代わった途端に問題発覚(^^;)。
livedoor blog の生ログって、月単位なのですね。
つまり、生ログを参照するページの URL は、
http://analyzer.livedoor.com/log/raw?page_id=22222&y=2006&m=4
などとなっていますが、「m=4」を指定しない限り 4月分のログは表示されない
(今月分のみ表示される)、
という仕様のようです。
livedoor blog の有料プランを始めてから初めての月代わりだったもので...
というわけで、生ログを取得する際に日付を指定できるように修正してみました。
livedoor.pl gcd date 2006-04-30 raw_log 100 -
などと、「date YYYY-MM-DD」ないし「date YYYY-MM」を指定することにより、
生ログを取得する日付ないし月を指定できます。
「raw_log 100 - 」は、生ログ 100ページ分 (2000行) を標準出力 (「 - 」)
に出力する、という意味です。
生ログを遡っていく途中で、指定した日付と異なる日付の生ログが得られたら、
それ以上の取得をストップするので、ページ数は多めに指定しておいて大丈夫です。
また、ついでに「ブログのエクスポート(バックアップ)」もサポートしました。
livedoor.pl gcd export_reserve
で、「エクスポートファイルの作成」を行ない、
livedoor.pl gcd export バックアップファイル名
で、エクスポートファイルをダウンロードして
「バックアップファイル名」で保存します。
以上の機能は、
livedoor blog の有料プランを選択していないと使用できませんが、
スタイルシート(CSS)および HTMLのテンプレートの取得は、
ブログのデザインを custom に設定していれば使用できます。
まず、livedoor blog の管理ページで、
「カスタマイズ/管理」-「デザインの設定」を選び、
デザインとして「カスタマイズ」を選択したときの URL を確認します。
例えば
http://cms.blog.livedoor.com/cms/design/edit?blog_id=1600549&id=11111
といった感じの URL になると思います。
「blog_id=1600549」および「id=11111」の数字を、
スクリプト先頭の
"BlogID" => 1600549,
"ID" => 11111,
の部分に設定しておいて、
livedoor.pl gcd css CSSファイル名
と実行すれば、スタイルシート(CSS) が「CSSファイル名」で保存されます。
「css」の代わりに、
「index_tmpl」「article_tmpl」「category_tmpl」「monthly_tmpl」
を指定すれば、それぞれ「トップページ」「個別記事ページ」
「カテゴリアーカイブ」「月別アーカイブ」の HTMLテンプレートを
保存できます。
一度のスクリプト実行で一括して保存することもできます:
livedoor.pl gcd css blog.css index_tmpl blog.html \
article_tmpl blog_article.html \
category_tmpl blog_category.html \
monthly_tmpl blog_month.html
「スタイルシート(CSS)」を、「blog.css」へ、
「トップページ」を、「blog.html」へ、
「個別記事ページ」を、「blog_article.html」へ、
「カテゴリアーカイブ」を、「blog_category.html」へ、
「月別アーカイブ」を、「blog_month.html」へ、
それぞれ保存します。
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 (exists $blogs{$_}) {
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 "date") {
$_ = shift;
if (/^(\d\d\d\d)-(\d\d)(?:-(\d\d))?$/) {
$Year = $1;
$Month = ($2 + 0);
$Date = $_;
} else {
die "date must be YYYY-MM-DD: $_\n";
}
} elsif ($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;
&help unless $file;
open(OUT, ">$file") || die;
my $url = "http://analyzer.livedoor.com/log/raw?page_id=$PageID";
if ($Date) {
$url .= "&y=$Year&m=$Month";
}
my $prepat = '\<td\b[^\>]*\>\<strong\>\<small\>';
my $postpat = '\<\/small\>\<\/strong\>\<\/td\b[^\>]*\>';
my $datematch = 0;
pages: 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\>)/o, $res->content)) {
if (/^\<small\>($datepat)\<\/small\>$/o) {
$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";
}
}
if (! defined($Date) || $date =~ /^$Date/) {
$datematch = 1;
print OUT $date, ",", join(',', @record), "\r\n";
} elsif ($datematch) {
last pages;
}
}
}
}
close(OUT);
} elsif ($type eq "export_reserve") {
my $url = "http://cms.blog.livedoor.com/cms/import/mt/export_reserve";
my $req = new HTTP::Request GET => $url;
my $res = $ua->request($req);
if (! $res->is_success) {
print STDERR "fail to reserve export";
exit 1;
}
} elsif ($type eq "export") {
my $file = shift;
open(OUT, ">$file") || die;
my $url = "http://cms.blog.livedoor.com/cms/import/mt/export";
my $req = new HTTP::Request GET => $url;
my $res = $ua->request($req);
print OUT $res->content;
close(OUT);
} else {
&help;
}
}
exit 0;
sub help {
print STDERR "Usage livedoor <blog> <opt>...\nblog: ",
join("\n ", keys %blogs), "\n",
'opt: date YYYY-MM
date YYYY-MM-DD
css <file>
index_tmpl <file>
article_tmpl <file>
category_tmpl <file>
monthly_tmpl <file>
raw_log <n> <file>
export_reserve
export <file>
';
exit 1;
}