Hatena::Groupperl

local $PERL_MEMO;

October 09, 2007

[][]はてなグラフAPIでデータ取得する時にLWP::UserAgent->get()の引数ではまった 23:58

ちゃんとpod読まない僕が悪いのですけど。

最近Twitterに嵌ってまして*1、先日Twitterの諸々のステータスをはてなグラフにポストするスクリプトを書いたんです。サンプルコードがあるのでデータの登録は簡単に出来たのですが、既にその日のデータが登録されているかのチェックにAPIからデータの取得をしたくなり、以下のような感じにしたところ、うまくいかない。

use strict;
use warnings;
use utf8;
use Encode qw/encode decode/;
use LWP::UserAgent;

binmode STDOUT => ":encoding(shiftjis)";
binmode STDERR => ":encoding(shiftjis)";

### 諸々の処理

my $ua = LWP::UserAgent->new();
$ua->credentials(
    'graph.hatena.ne.jp:80', # API HOST
    '',                      # API REALM
    'Cor_st',                # USERNAME
    '********',              # PASSWORD
);
my $res = $ua->get('http://graph.hatena.ne.jp/api/data', {
    graphname => encode('utf8', 'テスト'),
    type => 'json',
});

warn $res->code.": ".decode('utf8',$res->content);
### ここで "500: " ってなる。200が返ってきて欲しい。

### 以下

なんでだろー。post()のときはこれでうまくいっていたのに…get()ではWSSE認証はされないのかなーと思って中を見たりしたのですがそんなことはなく、get()でもちゃんとヘッダが追加されてました。そもそも認証うまくいかないと401が返ってくる。

なんでうまくいかないのかと思ってもう一度よくよく調べてみたら、どうやらget()では第2引数にフォームデータを渡すことが出来ない様子。podには

$ua->get( $url , $field_name => $value, ... )

っていうのがあって、この$field_nameをフォームデータと勘違いしてた。ここにはコールバック関数とかを指定するのだそうです。

じゃあどうしなくちゃいけなかったかというと$urlの末尾にクエリ文字列としてくっつけてget()する必要があったのでした。正しいget()の方法は以下。

my $res = $ua->get( encode('utf8', 'http://graph.hatena.ne.jp/api/data?graphname=テスト&type=json') );

warn $res->code.": ".decode('utf8',$res->content);
### 200: {"2007-10-08":"100"}

これでおk。get()はクエリ文字列で渡す。LWP::UserAgentの使い方がよく分かってないというお話でした。

それから、はてなグラフ数値登録APIのほうを見て気が付いたのですが、はてなグラフAPIのサンプルコード、非推奨のAPI使ってるみたい。

http://graph.hatena.ne.jp/api/dataのほうがお奨めらしいです。

*1:4月からやってるんだけどね。 http://twitter.com/Cor_st