Perl Hackers Hub

第4回 Twitterから学ぶ,Web APIのキホン(2)

この記事を読むのに必要な時間:およそ 3 分

LWP::UserAgentことはじめ

Webページのタイトルを取得するコード

Twitter Search APIへアクセスしたい気持ちを抑えつつ,まずは最小限の例としてgihyo.jpのHTMLを単純に取得し,タイトルだけを出力する例を見ていきましょう。

use URI;
use LWP::UserAgent;

my $uri = URI->new('http://gihyo.jp/');
my $ua = LWP::UserAgent->new();  …(1)
my $res = $ua->get( $uri );  …(2)
die $res->status_line if $res->is_error;  …(3)
my ($title) = $res->content
    =~ m!<title>(.+?)</title>!i;  …(4)
print "$title\n";

このスクリプトを実行すると,現在のgihyo.jpのタイトルが標準出力に出力されるはずです。以降で要所を解説していきます。

GETメソッドによるリクエスト/レスポンス処理の基本

(1)でオプションを指定せずにLWP::UserAgentオブジェクトを作成しています。もしユーザエージェントを「wpcrawler」⁠タイムアウトを30秒にしたければ,次のようにnewメソッドへハッシュを渡してあげるとよいでしょう。

my $ua = LWP::UserAgent->new( agent => 'wpcrawler',
                                       timeout => 30 );

getメソッドにURI文字列やURIオブジェクトを渡すと,実際にそのURIへGETリクエストが発生します。そして返り値としてHTTP::Responseオブジェクトが返ってきますので,それを(2)のようにして変数へ代入しておきましょう。

ここで出てきたHTTP::Responseはその名のとおりHTTPのレスポンスを汎用的に扱えるような一般的なモジュールです。もちろんHTTP::Requestというモジュールもあり,上記のgetメソッドでは内部的にそれを利用しています。

HTTP::Responseオブジェクトのis_successやis_errorメソッドは,そのHTTPレスポンスのステータスコードを見て条件分岐するのに使えます。is_successメソッドではそのステータスコードが200番台であれば真を,is_errorメソッドではそのステータスコードが400番台もしくは500番台であれば真を返します。

また,status_lineメソッドではステータスコードそのメッセージという文字列を出力します。たとえば200 OK404 Not Foundといった具合です。ですので(3)の部分は,もしレスポンスがエラーを返したら,ステータスコードとそのメッセージを出力しながら終了させるという意味です。

もしレスポンスがエラーを返さなかった場合には,(4)でそのレスポンスのコンテンツ,つまり実際のHTML文字列自体を取得して,正規表現でタイトルを切り取っています。

ここまでがLWP::UserAgentの最低限の使い方ですが,この程度を覚えておけば多くのWeb APIとのやりとりに対応できると思います。Twitter Search APIを利用する場合,(4)のレスポンスのコンテンツがJSONフォーマットになり,パースすることで取得結果を利用していくことになります。

結果をパースする

Twitter Search APIのレスポンスは,JSONとXML(Atom)で提供されています。今回はJSONをパースしてツイートを解析してみます。

JSONモジュール

JSONフォーマットを解析するにはJSON::XSモジュールやJSON::PPモジュールを使うのが一般的です。今回紹介するのはJSONモジュールなのですが,実際のところcpanシェルやcpanmコマンドなどで「JSON」と指定してインストールすると,JSON::XSがインストールできればそれが,もしできない場合はJSON::PPが入るという具合です。JSONモジュール自体がその2つのインタフェースを吸収する形になっているので,今回紹介する使い方を覚えればどちらが入っていようが特に問題ないはずです。

JSONテキストからの変換

ここでは,次の名前と値のペアのハッシュ構造を持つJSONを例に取ります。

  • user:yusukebe
  • message:おはよう

JSONにおける日本語文字列は,\uXXXX」という形式のUnicodeベースのASCII文字にエスケープがかけられていることが多いです。Twitter Search APIで取得できるJSONもそのようなものです。たとえば「おはよう」\u304a\u306f\u3088\u3046」にエスケープされています。

以下は,JSONメッセージをPerlのデータ構造に変換してから出力するスクリプトです。

use JSON qw( decode_json );
use Encode qw( encode_utf8 );

my $json_text =
'{"user":"yusukebe","message":"\u304a\u306f\u3088\u3046"}';
my $ref = decode_json($json_text);
print encode_utf8("$ref->{user} : $ref->{message}\n");

JSONモジュールのdecode_jsonメソッドをインポートして利用しています。このメソッドの返り値がPerlのハッシュリファレンス構造になっているので,そのままutf8フラグを落としつつ,printしています。

# 実行結果
yusukebe : おはよう

JSONテキストへの変換

ちなみに,Perlのデータ構造からJSONテキストへの変換もJSONモジュールで行えます。

use JSON;
use utf8;

my $json = JSON->new;  …(1)
$json->ascii(1);  …(2)
my $json_text =
$json->encode({ user => 'yusukebe', message => "おはよう" });
print "$json_text\n";

(1)のように,JSONモジュールはOOObject Orientedインタフェースにも対応しています。OOインタフェースの利用について簡単に補足すると,何度もencode/decodeメソッド呼び出す場合,一度JSONモジュールをnewメソッドでオブジェクト化しておくと,関数をインポートするより高速になります。

今回は先述した日本語などの\uXXXX」へのエスケープを有効にするために(2)としています。あとはJSONオブジェクトのencodeメソッドでPerlのハッシュリファレンスを渡してあげると,JSON形式のテキストに変換してくれます。

これでJSONのdecode/encodeができるようになりましたね。

# 実行結果
{"user":"yusukebe","message":"\u304a\u306f\u3088\u3046"}

著者プロフィール

和田裕介(わだゆうすけ)

(株)ワディット代表取締役,(株)オモロキCTO。未踏ユース「準」スーパークリエーター。

慶応義塾大学政策・メディア研究科にて,メディアデザインを専攻。ACM SIGGRAPH Emerging Technologiesに採択など。修士課程修了後,父親と共に起業。Perl等を使ったシステム開発を行いながら,個人でもWebアプリケーションをいくつか公開している。

ブログは『ゆーすけべー日記』:http://yusukebe.com/

コメント

コメントの記入