昨日書いた「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; }