タグ「webservice-simple」が付けられているもの

この記事見つけて

以前紹介した「これは便利!誰でも簡単にグラフを描けるAPIがGoogleから登場!『Google Charts』」ですが、PHPから簡単に操作できるようにしたライブラリが公開されています。

Google Charts APIをPHPから簡単に操作できるようにしたライブラリ『googChart』 | IDEA*IDEA」より

同じようにGoogle Charts API を扱う Perl 版が欲しかったので、WebService::Simple(0.09以上が必須) を継承する形で「WebService::Simple::Google::Chart」というモジュールを作ってみました。

パラメータを渡すと、その Chart のURLを返してくれて(get_url)、その Chart のイメージをファイルに書き出す(render_to_file)ことができます。以下がコードサンプルです。

use WebService::Simple::Google::Chart;

my $chart = WebService::Simple::Google::Chart->new;
my $url = $chart->get_url(
    {
        chs => "250x100",
        cht => "p3",
   },
    { foo => 200, bar => 130, hoge => 70 }
);

#http://chart.apis.google.com/chart?cht=p3&chl=bar%7Cfoo%7Choge&chs=250x100&chd=t%3A33%2C50%2C18
print $url . "\n";

#一度 get_url でパラメータを渡したら、ファイル名を指定するだけで書き出せる
$chart->render_to_file("foo.png");

特徴は、get_url 及び render_to_file の第2引数に、チャートにしたいデータを ラベル名 => 値 という形のハッシュリファレンスを渡せば、自動的に割合を出してくれて URL のパラメータにする点です。 なので、最大値をみつけて、それぞれの値をその数字で割るなんてことは不要になります(なるはずです)。 第一引数はデータ以外のチャートへのパラメータを書けばOKです。

WebService::Simple は LWP::UserAgent を継承しているので、今回のファイルに書き出すという機能が簡単に実装できました。実際 Chart.pm の中身はこんな感じでファイルに保存しています。

$self->SUPER::get( $request_param , ":content_file" => $filename );

CPAN はここ(ただし、0.01 はインターフェースが違う&バグを持っているので 0.02 以上推奨)

CodeRepos はここに置いておきます。修正、突っ込み大歓迎です。

ちなみに、 Google::Chart という hanekomu さんが作っているそのものずばりのモジュールがCPANにあって coderepos にもレポジトリを移してもらいました。 が、しかし、これだとラベル表示ができなくて、対応するためにコードいじろうと手をつけてみたら、 設計までも変えてしまいかねないことに気づき、別モジュールという形で作ることにしました。ということでこれをhanekomu さんに見せたい。

Google AJAX Search API ってその名の通り JavaScript から利用することを前提に作られているんだけど、 先ほどドキュメンテーションに「Flash and other Non-Javascript Environments」という項目が追加されました。 JavaScript 以外の環境から Google AJAX Search API をこんな風に使えますよと書かれているようです。 今まで、例えば Perl から Web ページを検索する時には、Google のそれは「JS からしか使えないんでしょ」とあきらめて、Yahoo! の検索 API をよく使っていたところ、これで Google の検索結果も利用できるようになります。 JavaScript のレイヤーより一つ下くらいのところで、API が使えるとなると可能性も広がるかと思います。 ということで、早速、WebService::Simple を使って、Perl から Google AJAX Search API を使ってみたよ。

サンプルを紹介する前にこの API の仕様について軽く解説。 ベースURL は

http://ajax.googleapis.com/ajax/services/search/web

で、それに以下のようなパラメータを渡すと結果が JSON 形式で返ってくる。

q : 検索クエリー
v : API のヴァージョン、現時点でのデフォルトは 1.0
rsz : 検索結果をどのサイズで返して欲しいか、デフォルトは small の4件、large を指定すると8件
hl : 何語のウェブから検索したいか、日本語の場合だと ja
start : 検索結果を何番目から取得したいか、デフォルトは 0、おそらく最大で 24 っぽい

詳しくはここを参照→Class Reference - Google AJAX Search API - Google Code

取得できる JSON の形式はこちらを参考に→Developer's Guide - Google AJAX Search API - Google Code

では、WebService::Simple を使ったサンプルを紹介。 WebService::Simple には JSON のパーサーもあるので検索結果を Dump するだけのスクリプトだったらこんな簡単に書けちゃいます。

my $google = WebService::Simple->new(
    base_url        => "http://ajax.googleapis.com/ajax/services/search/web",
    response_parser => "JSON",
    params          => { v => "1.0", rsz=> "large" }
);

my $response =  $google->get( { q => "cat" , start=> 0 } );
print Dump $response->parse_response;

次に、検索クエリーを入れるとその結果が表示されるだけの簡単な Web ページを作ってみます。 パースしたコンテンツをそのまま Template::Toolkit のテンプレートに渡すという方針です。 ただ、これを実現するにはちょっとしたハックが必要になりました。 JSON のモジュールを使ってパースされたオブジェクトには utf8 フラグが立ってないっぽいんですよ。 utf8 flagged な値も、TT に渡したいので、混在しちゃうと文字化けしちゃいます(その値を uri フィルターかけたいから、フラグを落としたくないのです、なんか間違ってたらツッコミください)。 そこで、以下のハックで JSON モジュールが返してくれるオブジェクトに utf8 フラグを立ててます。

use WebService::Simple;
use WebService::Simple::Parser::JSON;

my $parser = WebService::Simple::Parser::JSON->new; # パーサーを作る
$parser->{json}->utf8(1); # utf8 フラグが立ったオブジェクトを返してもらう
my $google = WebService::Simple->new(
    base_url        => "http://ajax.googleapis.com/ajax/services/search/web",
    response_parser => $parser, # パーサーオブジェクトを指定する
    params          => { v => "1.0", rsz => "large", hl => "ja" }
);

つまづいたのはこのくらい。完成版のPerl のコードと テンプレートは以下の通りです。

search.cgi

#!/usr/bin/perl

use strict;
use warnings;
use CGI;
use Template;
use WebService::Simple;
use WebService::Simple::Parser::JSON;

my $q     = CGI->new;
my $query = $q->param('query');
utf8::decode($query);
my $start = $q->param('start') || 0;

my $parser = WebService::Simple::Parser::JSON->new;
$parser->{json}->utf8(1);
my $google = WebService::Simple->new(
    base_url        => "http://ajax.googleapis.com/ajax/services/search/web",
    response_parser => $parser,
    params          => { v => "1.0", rsz => "large", hl => "ja" }
);
my $response = $google->get( { q => $query, start => $start } );

my $tt = Template->new();
my $html;

$tt->process(
    "search.tt",
    {
        query    => $query,
        response => $response->parse_response
    },
    \$html
);

print $q->header( -type => "text/html", -charset => "utf-8" );
print $html;

search.tt


<html>
<body>
<h1><a href="search.cgi">Google Search</a></h1>
<form action="" method="get">
<p>
<input type="text" name="query" value="[% query %]" />
<input type="submit" value="Google Search" />
</p>
</form>
<p>
[% SET count = response.responseData.cursor.estimatedResultCount -%]
[% IF count -%][% count %] pages[% END -%]
</p>
<dl>
[% FOREACH item = response.responseData.results -%]
  <dt><a href="[% item.unescapedUrl %]">[% item.title %]</a></dt>
  <dd>[% item.content %]</dd>
[% END -%]
</dl>
<div>
  [% FOREACH page = response.responseData.cursor.pages -%]
  <a href="?query=[% query | uri %]&amp;start=[% page.start %]">[% page.label %]</a>
  [% END -%]
</div>
</body>
</html>

ということで、Google AJAX Search API を WebService::Simple 使って利用してみました。 取得できる件数に制限があるのがちょっと残念ですが、この API なかなか重宝しそうです。

シンプルに Web API を叩ける WebService::Simple の現在の最新版はヴァージョン 0.09 です。 ヴァージョン 0.03 からスーパーハカーによる修正が入ったこともあり、機能が(Simpleという名前を崩さない程度に)増えたり、多少インターフェースが変わったりしました。 そこで WebService::Simple 0.09 の使い方を POD より詳しめに解説します。 # shipit が便利だったので、調子に乗ってやたら使いまくったらヴァージョンがどんどんあがっちゃった><

最初に、インターフェースの変更点をあげます。大きく変わったのは一点のみです。 例えば、Lingr の API を扱う場合、base_url は http://www.lingr.com/ になりますが、 各メソッドの URL は 例えば http://www.lingr.com/api/session/create という風に、メソッドごとに変化します。つまり base_url に api/session/create みたいなパスを追加したいということです。 そのためには、 get メソッド の パラメータ にそのパスを記載するんですが、0.03 の時と引渡し方が変更になっています。 第1引数に extra_path を指定するようになりました。

my $lingr = WebService::Simple->new(
    base_url => 'http://www.lingr.com/',
    param    => { api_key => "your_api_key", format => 'xml' }
);

my $response = $lingr->get( 'api/session/create', {} );

my $session = $response->parse_response->{session};

また、上記サンプルに記載されているように、get などで取得した WebService::Simple::Response オブジェクトをパースするには、parse_xml メソッドを今まで呼んででいましたが、parse_response メソッドを使うことを推奨しています(エイリアスを作っているので parse_xml でも動きます)。

あとは普通に使う分には今まで通りで問題ないです。 Flickr API を使ったキーワードによる検索結果を Dump するサンプルコードは以下のようになります。

use strict;
use warnings;
use WebService::Simple;
use Data::Dumper;

my $flickr = WebService::Simple->new(
    base_url => "http://api.flickr.com/services/rest/",
    param    => { api_key => "your_api_key", }
);

my $response =
  $flickr->get( { method => "flickr.photos.search", text => "cat" } );
print Dumper $response->parse_response;

response のキャッシュも以前と同じ書き方でできます。

use WebService::Simple;
use Cache::File;

my $cache = Cache::File->new(
    cache_root      => '/tmp/mycache',
    default_expires => '30 min',
);

my $flickr = WebService::Simple->new(
    base_url => "http://api.flickr.com/services/rest/",
    cache    => $cache,
    param    => { api_key => "your_api_key", }
);

次にこの WebService::Simple を継承したサブクラスを作って、もうちょっと楽に API を触れるという方法を紹介します。 例えば、Flickr API の flickr.test.echo 及び flickr.photos.search を呼び出す WebService::Simple::Flickr をこんな感じで作ります。

package WebService::Simple::Flickr;

use base qw(WebService::Simple);
__PACKAGE__->config(
    base_url   => "http://api.flickr.com/services/rest/",
);

sub test_echo {
    my ($self,$str) = @_;
    return $self->get( { method => "flickr.test.echo", name => $str } );
}

sub photos_search {
    my ($self,$str) = @_;
    return $self->get( { method => "flickr.photos.search", text => $str } );
}

そしたら外部から、よりスッキリとしたコードで API をたたくことができます。

use utf8;
use WebService::Simple::Flickr;
use Data::Dumper;

my $flickr =
  WebService::Simple::Flickr->new( param => { api_key => "your_api_key", } );

my $ref = $flickr->photos_search("富士山")->parse_response;
print Dumper $ref;

この API ごとにサブクラス化するという方法なんですが、Yappo さんが作った WebService::Simple::Cabinet を使う方法と、「ある API に特化したモジュールもしくはメソッドを作る」という点で似ています。WebService::Simple::Cabinet は YAML 形式などで API の定義をしますが、この場合は Perl モジュールを作っています。API を使うシチュエーションによってどちらか選ぶというのもいいと思います。

最後にパーサー、つまりAPI から返却されたコンテンツをパースするのに使うモジュールが選べるようになったという機能を紹介します。デフォルトでは XML::Simple でパースするようになっていますが、例えば XML::LibXML を使いたい場合は、WebService::Simple::Parser を継承して WebService::Simple::Parser::XML::LibXML モジュールを以下のように作成します( このモジュールはWebService::Simple に同封されています)。

package WebService::Simple::Parser::XML::LibXML;
use strict;
use warnings;
use base qw(WebService::Simple::Parser);
use XML::LibXML;

__PACKAGE__->mk_accessors($_) for qw(libxml);

sub new
{
    my $class = shift;
    my $args  = shift || {};
    $args->{libxml} ||= XML::LibXML->new;
    $class->SUPER::new($args);
}

sub parse_response
{
    my $self = shift;
    $self->libxml->parse_string( $_[0]->content );
}

1;

それで利用するスクリプトからは、WebService::Simple のコンストラクタの引数 response_parser の値で使いたいパーサのモジュールを指定します。

my $service = WebService::Simple->new(
    base_url        => "http://api.flickr.com/services/rest/",
    response_parser => 'XML::LibXML',
    params          => { api_key => "your_api_key" }
);

これで面白いのは、とりわけ XML で結果が返ってくる API 以外にも対応するところです。 例えば、JSON もしくは JSONP 形式で返却される API を扱うこともできます。 WebService::Simple::Parser::JSON はもう既に定義済みのものがあるので、以下のようなスクリプトを書くだけで、JSON もしくは JSONP を パースしてくれてデータを利用することができます。

use strict;
use warnings;
use WebService::Simple;
use Data::Dumper;

my $flickr = WebService::Simple->new(
    base_url        => "http://api.flickr.com/services/rest/",
    response_parser => 'JSON',
    params          => { api_key => "your_api_key", format => "json" }
);

my $response =
  $flickr->get( { method => "flickr.photos.search", text => "cat" } );
print Dumper $response->parse_response;

あとは POST にも対応したので、使いたい場合は post メソッドを get と同じ引数形式で呼び出せばおkだと思います。

dmaki(lestrrat)さん、tokuhirom に(まるごと)書き換えてもらった&Yappo さんが WebService::Simple::Cabinet を作ったおかげで、面白いモジュールになった気がします。感謝です。

CPAN に最新版があがっているので、もしよろしければご利用ください。

1

プロフィール

yusukebe

ゆーすけべー / yusukebe
Yusuke Wada
1981/12/23 生
天然パーマ Erogeek
HP Twitter mixi はてブ
yusuke (at) kamawada.com
more...

最近10件のアクション

  • yusukebe tweeted, "AVPhoneがいい感じになりつつある http://avphone.tv/"
  • yusukebe tweeted, "YAPC::Asia 2010 前夜祭の裏テーマは「私をYAPCに連れてって!」?? - ゆーすけべー日記 http://bit.ly/alRbZ8"
  • yusukebe tweeted, "@lovecall はい!!!"
  • yusukebe tweeted, "@lovecall 全然いいので、5分でまとめるようにしてください。頭数にいれておきます。よろ"
  • yusukebe tweeted, "@lovecall そうそう!!!!"
  • yusukebe tweeted, "@lovecall 前夜祭のLTで、Perl小説の話してよ♡"
  • yusukebe tweeted, "@lovecall 全裸みたいの??"
  • yusukebe tweeted, "PerlCasualでYAPC前夜祭を担当させていただくことになりました。テーマはWA(F)にしようかと思います。本編で話せなかったけど話してみたい人は教えてください!"
  • yusukebe tweeted, "@lovecall YAPC来る?"
  • yusukebe heard Blur – End of a Century

最近のブログ記事

  • YAPC::Asia 2010 前夜祭の裏テーマは「私をYAPCに連れてって!」??

    *これは現時点ではYAPC::Asia本体、JPAとは全く関係のない見解です。 えー、10月14日に開催されるYAPC::Asia 2010前夜祭を PerlCasualで担当させていただくことになりました。そこで、 まだ正式に決まった訳ではないのですが、 プランを組んでみました。スピーカーを依頼する部分、 かなりの無茶ぶりを含んでいます。 ずばり、テーマは「Web Application (Framework)」です。 今まで3回やってきて要望が多いのにも関わらず触れられったものです。 Frameworkに括弧つけてるのはそれそのものじゃなくて それを応用した例の話もあってもいいかと思ったからです。 そして、裏のテーマは「私をYAPCに連れてって!」。 謎です。 詳細のタイムテーブルもプランの中にはあるのですが、 ちょろっとずつ決定していくということで、 今のところ見せられる概要はこんなんです。 基調講演(京都の人) Catalystを始めよう(全裸Bros.) WAF作者の集い LT(なんでもあり) 前夜祭はYAPCチケットを持っている人は無料、 持ってない人は1000円を払えば参加可能になる予定です。...

  • YourAVHostが最強のPC無料エロサイトになった件

    エロサイトとしては驚異的な、 はてなブックマーク数のべ(ドメイン移行したので「のべ」になってます)1,000以上を集めている YourAVHost。 YourFileHostのエロ動画を女優名別に探せるというシンプルなものでした。 今でもそれなりに人気があって検索語「youravhost」でたどり着く人が一番多いです。 そのYourAVHostが9月1日、ひっそりとリニューアルして(PC向け無料の)エロサイト最強になったっぽいので、 紹介です。 YourFileHost以外のエロ動画もAV女優名別、ジャンル別で探せる YourAVHost開始当初は通常検索できないYourFileHostの動画とAV女優名を結びつけたということが 一番の特徴だったわけです。今回のリニューアルでは、PornStarというエロサイトと統合したことにより、 YourFileHost以外にもMegaporn、XVideos、Empflixなど他5サイト以上の動画がAV女優名から探すことができるように なりました。また、個人の性癖にあわせたジャンル、つまり、「3P」や「パイパン」といった「タグ」からも エロ動画をみつけることができます。 YourFileHost動画もその場で再生 各種エンベッド(埋め込み)に対応し、 なんとYourFileHostもサイト内で再生可能になりました。 動画サイトにいかなくとも派手な広告の無いシンプルな画面で、再生できるので ヌクのに最適です。 素人動画も見れる AV女優以外に素人っぽい動画は素人というカテゴリーに入れられるようになりました。 素人動画もいいっすよね!! リニューアルを施してからサイト滞在率がなんと10倍近く跳ね上がりました。 Googleに再インデックスがちゃんとされたらサイト内検索つけようと思います。 そしたらもっと最強ですね。...

  • PerlスクリプトでWebサイト死活管理

    個人で作ってるサイトの死活監視を「再び」ちゃんとやろうと思っています。 そこで、Nagios使うまでも無く、Kazuhoさんの Kazuho@Cybozu Labs: 監視とは継続的なテストである、という話 (もしくは cronlog とテストスクリプトを組み合わせた監視手法について) みてシンプルに死活監視できるよなーと思って、 「Perlスクリプト」を書いてみました。 「死活」のみの監視なんで、サイトが正常では無かったらメールを飛ばすだけでいいという想定です。 設定をYAMLで持たせたかったり、メールをPerlから送りたかったりしたんで、 少しKazuhoさんのやってることより複雑になりましたが、まぁ簡単です。 #!/usr/bin/perl use strict; use warnings; use LWP::UserAgent; use Email::Sender::Simple qw(sendmail); use...

  • ディレクトリ配下の.pmファイルでuseしているCPANモジュールを一気にインストールする

    これが一番簡単っぽい? Module::Usedなるモジュールをインストールして付属のmodules-usedコマンドを使ってみる。 $ cpanm --sudo Module::Used $ modules-used ./ | cpanm --sudo --skip-installed 今、お試し中だよ。うまくいけば、 Makefile.PLのrequiresちゃんと書いてない時とか便利だね。...

  • 話題のサイトをみつけるならTwib! - リニューアルしたよ

    Twitterでつぶやかれた日本語ポストを収集して人気順に並べるサービスTwibがリリース一周年記念ということでリニューアルしたよ。 はてぶに似たデザインになって見やすくなって、はてぶとは違ってみんなのツイート付きだったりして楽しいよ! いろいろ機能が追加されたけど目玉は、「バズワード機能」。 最近のツイートから特徴的な言葉を抽出してて、朝方だと「朝焼け」が大きな文字で表示されたりするよ。 もちろん、それと関連するTwitPicの写真とか見れるよ! しかも、サイト上でそのまま表示(エンベッド)されるから便利だね。 以下に、リニューアルの改善点を挙げるよー。 1. インターフェースデザイン刷新 インターフェースを全面的にリニューアルしました。 トップページにより価値の高い記事をカテゴリ分けを行うことにより表示させています。 2. バズワード機能の追加 つぶやきから特徴的な言葉の頻出を計ることにより、 「今」話題の「バズワード」を右上に常に表示しています。 バズワードと関連のあるサイト情報を一覧することが可能です。 例えば、朝方ですと、「朝焼け」といった単語が大きな文字で表示され、 多くのユーザーが朝焼けの写真等をtwitpicなどの写真サービスを使い アップロードしている模様がわかります。 3. 「今、影響力のあるユーザー」表示 直近のRT(リツイート)された回数を数えることにより影響力のあるユーザーを表示する機能を 追加しました。 4....


SEO対策 エロワード

閉じる