PerlでJSONデータ・JSONPデータを処理する方法です。
1.JSONデータを処理する
JSONPデータの処理を解説する前に、JSONデータの処理について簡単に紹介します。
外部APIを起動し、次のようなJSONデータを受信したと想定します。
[
{
'link' => 'http://user-domain/aaa.html',
'title' => "テスト1"
},
{
'link' => 'http://user-domain/bbb.html',
'title' => "テスト2"
},
{
'link' => 'http://user-domain/ccc.html',
'title' => "テスト3"
}
];
この受信データの場合、次のようにJSONモジュールを利用することでPerlで処理できるようになります。
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use JSON;
use LWP::UserAgent;
my $q = new CGI;
print $q->header( -charset => "utf-8" );
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new( GET => '外部APIのURL' );
my $res = $ua->request( $req );
# $res->contentにJSONデータ
my $data = from_json( $res->content );
foreach (@{$data}) {
print $_->{ link };
print $_->{ title };
}
下のコードによる実装も可能です。他にもあるようですがここでは割愛します。
my $json = new JSON;
my $perl_scalar = $json->decode($json_text);
2.JSONPデータを処理する
本題はここからで、まず、はてなブックマークの人気エントリー取得用APIに「json」をつけて起動するとJSONデータを取得できるという情報がありました。
http://b.hatena.ne.jp/entrylist/json?url=http%3A%2F%2Fwww.koikikukan.com%2F&sort=count
が、実際には次のようなJSONPデータが返却されてしまいます(API起動方法が間違っていたらすいません)。データの一部は省略しています。
([
{
'link' => 'http://user-domain/aaa.html',
'title' => "テスト1"
},
{
'link' => 'http://user-domain/bbb.html',
'title' => "テスト2"
},
{
'link' => 'http://user-domain/ccc.html',
'title' => "テスト3"
}
]);
ということで、JSONPをPerlで処理する方法が必要になりました。
JSONデータをPerlで処理するには、1項のJSONやJSON:Syckなどが用意されていますが、JSONPについてはサーバ処理(JSONPデータを返却する処理)はありましたが、クライアントとして処理するモジュールやサンプルがみつけらませんでした。
よって力技ですが、次のようにJSONPデータにある先頭と末尾のカッコを除去して、JSONデータに変換してからJSONモジュールで処理してみました(赤色部分)。
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use JSON;
use LWP::UserAgent;
my $q = new CGI;
print $q->header( -charset => "utf-8" );
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new( GET => '外部APIのURL' );
my $res = $ua->request( $req );
my $content = $res->content;
$content =~ s/^\((.*)\);$/$1/;
my $data = from_json( $content );
foreach (@{$data}) {
print $_->{ link };
print $_->{ title };
}
が、間違いなく適切な方法があると思ってますので、誰かが正解をつぶやかれたらこの記事を修正したいと思います。他力本願ですいません。
ちなみに、さきほどのJSONPデータを正しいJSONPとして処理したい場合は、はてなブックマークの人気エントリー取得用APIのクエリパラメータに「callback=xxx」を付与します。
<pre><code>http://b.hatena.ne.jp/entrylist/json?url=http%3A%2F%2Fwww.koikikukan.com%2F&sort=count&callback=foo</code></pre>
これでJSONPデータが返却されます。
foo([
{
'link' => 'http://user-domain/aaa.html',
'title' => "テスト1"
},
{
'link' => 'http://user-domain/bbb.html',
'title' => "テスト2"
},
{
'link' => 'http://user-domain/ccc.html',
'title' => "テスト3"
}
]);