こんにちは! この前会社のCentOS4のサーバをyumったらPerl5.8.5のパッケージが更新されてしまい、CPANから入れたEncodeモジュールがパッケージのでデグレードしてしまい、メール送信で使っていたencode('MIME-Header-ISO_2022_JP', $foo )が動かなくなって涙目になりました。
さて、前回実用! Perlで少しでもSBMのブックマーク数を多く見せる - perl-mongers.orgでは、いろいろなソーシャルブックマークサービス(以下SBM)に用意されたWeb APIにアクセスし、ブックマーク数の合計をとるということをやりました。
今回は、SBMから得られる特定URLのブックマーク数が、イメージで得られるタイプの場合、どうやって数値として使えるか、というのをやってみます。本来想定された用途以外の使い方にチャレンジする、という意味では、Hackと言えると思います。
~~~
たとえば、FC2ブックマーク、画像としてブックマーク数を表示できるようになっています。
http://bookmark.fc2.com/image/users/http://perl-mongers.org/
で、

が得られます。
コンピュータが画像から文字を解読するのは大変
SBMから得られる画像に数字が書いてある場合、その画像から数字を認識させるのはかなり困難です。あらかじめ得られる画像データの特徴リストを持っておき、それと照合する、なんてことをすれば簡単になりますが、SBMサービス側の気まぐれで、「画像内の数字をかっこよくしよう」、なんてやられてしまった日には涙目です。
というわけで、画像を解析して数字を得るって言うのはあんまり現実的ではないです。
隠れたところにブックマーク数として採用できるデータが!
さて、画像を解析するのがボツになったので、じゃあどうやって、ブックマーク数の情報を取得するのか、という話なんですけれども、先ほどの
http://bookmark.fc2.com/image/users/http://perl-mongers.org/
にブラウザでアクセスすると、
ブラウザのアドレス欄が、"http://bookmark.fc2.com/icons/00002.png"とかになっていることに注目。つまり、画像表示のために、画像アイコンのURLにリダイレクトされているのです。
このURLの中に、なにやらブックマーク数として採用できそうな文字列が入っているので、これを利用します。
リダイレクト先のURLだけを取得
PerlでHTTPの通信をするときによく使われる、LWP::UserAgentを使います。リクエスト用URLをGETすると、ヘッダに、転送先のURLが入って帰ってくるので、それを正規表現で数字部分だけ取り出し、数値として取り扱います。
下の例では、画像として取得できるサービス一般で使えるようにしてみました。
各ソーシャルブックマークサービス(SBM)のブックマーク数画像表示APIを調べた ::: creazy photograph [creazy.net]
にて、各SBMにて、画像として取得するときのリクエスト用URLと、リダイレクト先のURLが書いてありますので、そのようにやってみます。なお、@niftyクリップと、POOKMARKはこっちで調査して付け加えました。
(2008-07-06 13:06訂正:スクリプトの名前をsmb_img_count.plからsbm_img_count.plに変更。livedoor用画像ファイル取得アドレスがYahoo!用のものになっていたのを訂正。また、動作がわかりやすいように、リダイレクト先のURLを表示するようにし、実行例も変更しました。http://b.hatena.ne.jp/kits/20080706#bookmark-9198443より指摘いただきました。)
Filename: sbm_img_count.pl
use strict;
use warnings;
use LWP::UserAgent;
our $sbms = {
hatena =>
{
proxy => 'http://b.hatena.ne.jp/entry/image/',
regexp => '/(\d+)\.png',
},
livedoor =>
{
proxy => 'http://image.clip.livedoor.com/counter/',
regexp => '/(\d+)$',
},
yahoo =>
{
proxy => 'http://num.bookmarks.yahoo.co.jp/image/large/',
regexp => '/(\d+)$',
},
buzzurl =>
{
proxy => 'http://api.buzzurl.jp/api/counter/v1/image?url=',
regexp => '/(\d+)\.gif',
},
fc2 =>
{
proxy => 'http://bookmark.fc2.com/image/users/',
regexp => '/(\d+)\.png',
},
nifty =>
{
proxy => 'http://api.clip.nifty.com/api/v1/image/counter/',
regexp => '/(\d+)\.png',
},
pookmark =>
{
proxy => 'http://pookmark.jp/count/',
regexp => '/(\d+)$',
},
};
my $url = 'http://perl-mongers.org/';
print 0
+ get_sbm( 'hatena' , $url )
+ get_sbm( 'livedoor', $url )
+ get_sbm( 'yahoo' , $url )
+ get_sbm( 'buzzurl' , $url )
+ get_sbm( 'fc2' , $url )
+ get_sbm( 'nifty' , $url )
+ get_sbm( 'pookmark', $url );
print "\n";
exit;
sub get_sbm {
my $service = shift;
my $url = shift;
return get_sbm_imageicon( $service, $url )
}
# ブックマーク件数イメージ提供サービスから件数取得
sub get_sbm_imageicon {
my $servce = shift;
my $url = shift;
our $sbms;
my $ua = LWP::UserAgent->new();
$ua->agent('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)');
my $method = 'GET';
#my $method = 'HEAD';
my $req = HTTP::Request->new( $method,
$sbms->{$servce}->{proxy}.$url );
my $res = $ua->simple_request($req);
my $location = $res->header('location');
print "$location\n";
my $count = 0;
if ( $location =~ m|$sbms->{$servce}->{regexp}| ) {
$count = 0 + $1;
}
return $count;
}
実行例:
$ sbm_img_count.pl
http://b.hatena.ne.jp/images/users/normal/00134.png
http://image.clip.livedoor.com/img/users/small/00019.png
http://thumbnail.yimg.jp/number/large/7
http://cdn.buzzurl.jp/static/image/num/1.gif
http://bookmark.fc2.com/icons/00002.png
http://clip.nifty.com/images/counter/00000.png
http://pookmark.jp/images/count/3
147
$
便利に使うには、コマンドラインからの入力が@ARGVに入るので、コマンドラインからURLを入れて問い合わせるように改造する、CGI.pmモジュールを使って、URLのクエリーから問い合わせるように改造する、等々できるんじゃないかなと思います。
[続きを読む]以降では、画像でしかブックマーク数の情報を提供していないSBMで、SBM運営会社の代わりに、XML-RPCインターフェースのAPIを用意するというあさっての方向に突っ走ってみます。