先日サービスにアクセス解析を付けることになり、リファラの集合を束ねて欲しいと言われた。つまり、あらゆるURLから同じblogのものであるとか、同じニュースサイトであるとかをグルーピングして欲しいと言う事だ。これって結構ややこしい。
イメージ的には
http://polog.org/0.php
http://polog.org/1.php
http://polog.org/2.php
とかあったら、"http://polog.org/"で束ねられるじゃん、とか言われそうだが、そうも行かない。
blogにはありとあらゆる階層にページがあるので
http://polog.org/index.php
http://polog.org/archives/cat1/
http://polog.org/archives/2007/02/
URLだけではリファラ群を束ねるのが難しいのだ。voxならドメイン、fc2なら第一階層がユーザのルートディレクトリだ。
てな訳で僕のアイデアとしては、まっとうなblogサービスならrel="alternate"でrss付いてる筈なので、その中身をパースしてルートディレクトリをチェックすれば良い。authorも分かるしアクセス解析を閲覧するユーザには分かり易い。そして以降同じrssのurlを見ているページはまとめてしまえば良い。
などと言ったんだけどもう面倒くさいから第一階層(http://hoge.com/hoge/)でまとめようと言う話になってしまった。そんな。
前置きが長くなったけど以上のアイデアを実行するPerlコードを書いた。
use LWP::Simple;
use strict;
my $url = $ARGV[0];
$url =~ m%(http://[^/]+)(/.*/)?%;
my $domain = $1;
my $base = $1.$2;
my $html = get($url);
if($html =~ m%<link rel="alternate".+?type="application/(?:atom|rss)¥+xml".+?href="(.+?)".*?>%){
my $rss_url = $1;
$rss_url = ($rss_url =~ m%^http:%) ? $rss_url :
($rss_url =~ m%^/%) ? $domain. $rss_url :
$base.$rss_url;
my $rss = get($rss_url);
my $author = ($rss =~ m%<dc:creator>(.+?)</dc:creator>%) ? $1 :
($rss =~ m%<author>[^<]*?<name>(.+?)</name>[^<]*?</author>%) ? $1 :
'';
my $home = ($rss =~ m%<link>(.+?)</link>%) ? $1 :
($rss =~ m%<link rel="alternate".+?type="text/html".+?href="(.+?)".*?>%) ? $1 :
'';
my $title = ($rss =~ m%<title>(.+?)</title>%) ? $1 : '';print "$title, $author, $home¥n";
}
alternateがあったら読みに行き、rss2,atom関係なくauthorとblogホームの情報を引っ張る。当たり前だけどxml tree作るのは面倒なのでgetして正規表現。
% perl hoge.pl http://blog.goo.ne.jp/hachitori/e/6cef002082f319664aa186b391a8dd51
sablog 18, hachitori, http://blog.goo.ne.jp/hachitori
これ書いたの20分ぐらいだと思うんだけど、現場でやらせて下さいって言っちゃったらColdfusion使って実装なんだこれが。Coldfusionでrobotて。
風邪で朦朧としているので乱文失礼。
(追記)
title足した。