仙石浩明の日記

2006年5月1日

livedoor blog 生ログ取得スクリプト (2)

昨日書いた「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;
}
Filed under: プログラミングと開発環境 — hiroaki_sengoku @ 08:45

コメントはまだありません »

コメントはまだありません。

この投稿へのコメントの RSS フィード。

コメントする