2008年08月24日

はてなダイアリーキーワード連想語APIとXMLRPC::Liteでハマった

 はてなダイアリーキーワード連想語APIを使用しようとして、日本語処理でハマったので書いておきます。
 はてなダイアリーキーワード連想語APIそのものについては、リンク先を見ていただくとして、サンプルプログラム(Perl版)をとりあえずそのまま動かしてみました。
 結果、検索対象がASCIIならば動くが、日本語だと結果が返ってこない

 あっちこち調べていたら、次のことがわかりました。
  1.XMLRPC::LiteにUTFフラグ付きの文字を渡すと怒られる(そのくせ結果はフラグ付きで返してくる
  2.XMLRPC::Liteにマルチバイト文字をbyte列(≒UTFフラグなし)で渡すと勝手にBASE64エンコードする
  3.はてなダイアリーキーワード連想語APIはBASE64エンコードされた文字列の入力に対応していない

//続きは追記で//
 で、解決策。
 1については、とりあえず置いておいて……
 2・3については、 XMLRPC::Data->type(string => '文字列') とすることでBASE64エンコードされるのを防ぐことができます。(blog.bulknews.netさんとこのエントリー

 さて、1について。スクリプトをUTF8(use utf8;)で書いているのならば、スクリプト中の変数に代入したマルチバイト文字にはUTFフラグがついているはずです。ですので、XMLRPC::Liteに渡す前にencodeしてフラグを落としてやらなければ怒られるはずです。
 しかし、どうも XMLRPC::Data->type(string => '文字列') の過程で勝手に処理してくれているらしい。(実際、Encode::is_utf8でフラグを調べてみると、変換前はフラグ付き、変換後はフラグが落ちています。)
 ※Encode::is_utf8($string)で、$stringにUTFフラグがついていれば真を返します。

 そんなわけで、はてなダイアリーキーワード連想語APIに日本語を投げるPerlスクリプトはこんな感じになります。

#!/usr/bin/perl
use strict;
use warnings;
use XMLRPC::Lite;
use Encode;
use utf8;

my @word = ('白い悪魔','魔砲少女');
my @word_key;


foreach(@word){
push(@word_key,XMLRPC::Data->type(string => $_)) ;
}

my $res = XMLRPC::Lite
->new
->proxy('http://d.hatena.ne.jp/xmlrpc')
->call(
'hatena.getSimilarWord',
{
wordlist => [@word_key]
});

print Encode::encode('utf-8',"【(@{word})に対する連想語】\n");

if(my $fault = $res->fault){
warn "$_ => $fault->{$_}" for(keys %$fault);
}else{
print Encode::encode('utf-8',$_->{word}),"\n" for(@{$res->result->{wordlist}});
}
exit;

そんでもって、シェルでの実行結果

【(白い悪魔 魔砲少女)に対する連想語】
ガンバの冒険
オタクの常識
管理局の白い悪魔
霧雨魔理沙
魔法
成恵の世界
関係
連邦の白い悪魔
魔法少女
東方Project
高町なのは
アニメ
魔法少女リリカルなのは
白い魔王
主人公
シリーズ


実際に使う際には、キャッシュ機構を組み込みましょう。
posted by 鯖缶 at 03:32 | Comment(0) | TrackBack(0) | ただいま開発中 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

※ブログオーナーが承認したコメントのみ表示されます。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/105238732

この記事へのトラックバック