久々の勝手に添削コーナ。今回は、hyukiさんのこちら。
結城浩のはてな日記Amazon Web Servicesを使って、ISBN-13からASINを取得するPerlプログラムを作ってみました。
まずは添削結果。
#!/usr/local/bin/perl use strict; use warnings; use CGI; use LWP::Simple; use XML::Simple; use URI; my $aws_access_key_id = 'YOUR AWS ACCESS KEY'; # For debug. my $OUTPUT_ENCODING = 'UTF8'; # Set up ISBN. my $isbn = shift or die "$0 [ISBN]"; # Set up URL. my $uri = URI->new('http://webservices.amazon.co.jp/onca/xml'); $uri->query_form( Service => "AWSECommerceService", AWSAccessKeyId => $aws_access_key_id, Operation => "ItemLookup", IdType => "ISBN", ItemId => $isbn, SearchIndex => "Books", ResponseGroup => "Request,Small", Version => "2007-01-15", ); # Retrieve result. print "ISBN: $isbn\n"; my $response_string = get($uri); my $response_hashref = XMLin($response_string); # Compose output string. my $output = <<"EOD"; ASIN: $response_hashref->{Items}->{Item}->{ASIN} Title: $response_hashref->{Items}->{Item}->{ItemAttributes}->{Title} Author: $response_hashref->{Items}->{Item}->{ItemAttributes}->{Author} EOD # Print as string. binmode STDOUT => ":encoding($OUTPUT_ENCODING)"; print $output; __END__
ポイントはURIを文字列でなくてURI
オブジェクトで処理していること。これのquery_form()
メソッドを使うと、このようにquery部分がすっきりと書けます。あと、ISBNの指定は決め打ちではなく引数にしてあります。
さすがhyukiさんだけあって、添削するほど汚いコードではないのですが、URIモジュールはLWPを煎れればもれなく付いてくるので紹介した次第です。
おまけ
AJAX版を以下に作ってみました。
ISBN: | |
ASIN: | |
Title: | |
Author: |
function $(id){ return document.getElementById(id) }; ISBN2ASIN = function(proxy, callback){ this.proxy = proxy || 'http://www.dan.co.jp/~dankogai/aws/isbn2asin.cgi'; this.callback = callback || 'jsonp'; this.parse = function(isbn, callback){ if (! callback) callback = this.callback; var script = document.createElement('script'); script.id = this.proxy + '/' + callback + '/' + isbn; script.charset = 'UTF-8'; script.src = script.id; document.lastChild.appendChild(script); }; return this; } var isbn2asin = new ISBN2ASIN(); function parse_jsonp(jsonp){ if (jsonp.Items.Request.IsValid == "False"){ $('aws.asin').innerHTML = jsonp.Items.Request.Errors.Error.Message; $('aws.title').innerHTML = ''; $('aws.author').innerHTML = ''; }else{ $('aws.asin').innerHTML = jsonp.Items.Item.ASIN; $('aws.title').innerHTML = jsonp.Items.Item.ItemAttributes.Title; $('aws.author').innerHTML = jsonp.Items.Item.ItemAttributes.Author; } } </script> <table style="border: outset 1px; padding: 0.5em"> <tr><td>ISBN:</td><td><input id='isbn' type="text" value="978-4844322894"> <input type="submit" onclick="isbn2asin.parse($('isbn').value, 'parse_jsonp')"></td></tr> <tr><td>ASIN:</td><td id="aws.asin"></td></tr> <tr><td>Title:</td><td id="aws.title"></td></tr> <tr><td>Author:</td><td id="aws.author"></td></tr> </table>
サーバー側のisbn2asin.cgiはリンクしておくに留めます。
Enjoy!
Dan the Just Another AWS Hacker
See Also:
・from_toの第一引数にはUTF8フラグOffのものを渡すべき
・:encoding()指定はUTF8フラグOnのものに効果がある
ということです。