Quantcast
Channel: 小粋空間
Viewing all articles
Browse latest Browse all 219

PerlでJSONPデータを処理する方法

$
0
0


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&amp;sort=count&amp;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"
  }
]);

Viewing all articles
Browse latest Browse all 219

Trending Articles