さて、Amazon Web サービスの件の続き (前回はこちら) です。
前回でやっと、 XML/HTTP 経由で日本語のキーワード検索をかけられるようになったわけですが、 ちょっと気になるのは順番です。 マニュアルを読むと順序は optional パラメータになっていて、 標準だともっとも基本的な「売れてる順」になるのかな?
どうやら、ソートに関しては「sort=...」という記述を、 URI のリソースパスの部分に入れればいいみたいなんだけど、 その部分はドキュメンテーションがイマイチ。 Amazon.co.jp のページのソースを見て想像すると、 「sort=+daterank」と入れれば、 「発売日の新しい順」でのソートができるようだ。 ということで、ちょっと改造してみよう。
# Hack: Following parameter is needed to pass Japanese UTF-8 encoded # characters to AWS. I don't know why it is needed, and it has no # effects on English queries (as far as I experienced). # See, http://forums.prospero.com/n/mb/message.asp?webtag=am-assocdevxml&msg=2704.1&ctx=0 my $jphack = '&__mk_ja_JP=' . uri_escape('カタカナ'); my $resource = "/onca/xml3?t=$tag&dev-t=$devt&KeywordSearch=$esckeyword&" . "mode=$category&type=$type&page=1&f=xml&locale=jp$jphack";
my $sort = '+daterank'; # Hack: Following parameter is needed to pass Japanese UTF-8 encoded # characters to AWS. I don't know why it is needed, and it has no # effects on English queries (as far as I experienced). # See, http://forums.prospero.com/n/mb/message.asp?webtag=am-assocdevxml&msg=2704.1&ctx=0 my $jphack = '&__mk_ja_JP=' . uri_escape('カタカナ'); my $xsort = ''; if ($sort) { $xsort = '&sort=' . uri_escape($sort); } my $resource = "/onca/xml3?t=$tag&dev-t=$devt&KeywordSearch=$esckeyword&" . "mode=$category&type=$type&page=1$xsort&f=xml&locale=jp" . "$jphack";
さて、これが「広末涼子」in books-jp の検索にどう影響を与えるだろうか? 結果はこうだ。
実際に Amazon の和書のページから同様の検索を行うと、 この検索結果が正しいことがわかる。 とはいっても、広末涼子では果たしてデータが正しいのか、 私の知識範囲では判断できないので (笑)、 「椎名林檎」 in music-jp で検索してみよう。 検索キーワードの部分をこう変更してみる。
my $keyword = "椎名林檎"; # Search keyword my $type = 'lite'; my $category = 'music-jp';
さて、結果はいかに?
おい…、何の順番かわからないよ…。一頻り悩んでいろいろ試すと、 books-jp の範囲では問題なく発売日順の検索ができることがわかった。 要するに、ソート順はカテゴリ依存の部分があるようだ。 マニュアルをよく読むと、確かにそれらしき記述はあるのだが、 不明な個所がたくさんあるので、Amazon.co.jp のページのソースを読むことで、 ある程度判明。結果はこんな感じ。結構メチャクチャ。
Amazon.co.jp カテゴリ名 | 発売日ソートキーワード |
---|---|
books-jp | +daterank |
music-jp | -orig-rel-date |
classical-jp | -orig-rel-date |
vhs-jp | -orig-rel-date |
dvd-jp | -orig-rel-date |
software-jp | -release-date |
videogames-jp | -release-date |
よし、それではさっきの「椎名林檎」 in music-jp の検索をもう一度やってみよう。 ソートのキーワードを -orig-rel-date に書き換えるぞ。
my $sort = '-orig-rel-date';
結果はどうだ? 今度は OK みたいだな! 『茎 (STEM)』が 2 つ入っているのは限定版と通常版だね。素晴らしい。
てなことで、この部分はもう少し汎用的に、こんな風に変えてみるかな?
# Hack: Following parameter is needed to pass Japanese UTF-8 encoded # characters to AWS. I don't know why it is needed, and it has no # effects on English queries (as far as I experienced). # See, http://forums.prospero.com/n/mb/message.asp?webtag=am-assocdevxml&msg=2704.1&ctx=0 my $jphack = '&__mk_ja_JP=' . uri_escape('カタカナ'); # "sort" key for newer products depends on the categories... my %sort_keys = ( 'books-jp' => '+daterank', 'music-jp' => '-orig-rel-date', 'classical-jp' => '-orig-rel-date', 'vhs-jp' => '-orig-rel-date', 'dvd-jp' => '-orig-rel-date', 'software-jp' => '-release-date', 'videogames-jp' => '-release-date', ); my $xsort = ''; if ($sort_keys{$category}) { $xsort = '&sort=' . uri_escape($sort_keys{$category}); } my $resource = "/onca/xml3?t=$tag&dev-t=$devt&KeywordSearch=$esckeyword&" . "mode=$category&type=$type&page=1$xsort&f=xml&locale=jp" . "$jphack";
うーむ、なかなか難儀だな…。 とりあえず、もう少し体裁を直して、 本日までの作業状態をまとめてみよう。 さしあたって、こんな感じだ。 関数「amazonXmlHttpQuery()」にまとめてみた。
#!/usr/local/bin/perl # Amazon Web サービス XML/HTTP テストスクリプト # Encoding: UTF-8 (unix) # Don't save this script as Shift-JIS or EUC-jp!! # # Copyright (c) 2003 by # 細川達己 (Tatsumi Hosokawa) <hosokawa@FromTo.Cc>, # All rights reserved. use strict; my $keyword = '広末涼子'; my $type = 'lite'; my $category = 'books-jp'; print amazonXmlHttpQuery($keyword, $type, $category); use Net::HTTP::NB; use URI::Escape; use IO::Select; # Database query to Amazon.co.jp database via XML/HTTP # (newer products in keyword search results) sub amazonXmlHttpQuery($$$) { my ($keyword, $type, $category) = @_; my $esckeyword = uri_escape($keyword); my $tag = 'MYTAG'; # Fill your "associate ID" my $devt = 'MYDEVT'; # Fill your "developer token" my $host = 'xml.amazon.com'; # Hack: Following parameter is needed to pass Japanese UTF-8 encoded # characters to AWS. I don't know why it is needed, and it has no # effects on English queries (as far as I experienced). # See, http://forums.prospero.com/n/mb/message.asp?webtag=am-assocdevxml&msg=2704.1&ctx=0 my $jphack = '&__mk_ja_JP=' . uri_escape('カタカナ'); # "sort" key for newer products depends on the categories... my %sort_keys = ( 'books-jp' => '+daterank', 'music-jp' => '-orig-rel-date', 'classical-jp' => '-orig-rel-date', 'vhs-jp' => '-orig-rel-date', 'dvd-jp' => '-orig-rel-date', 'software-jp' => '-release-date', 'videogames-jp' => '-release-date', ); my $xsort = ''; if ($sort_keys{$category}) { $xsort = "&sort=" . uri_escape($sort_keys{$category}); } my $resource = "/onca/xml3?t=$tag&dev-t=$devt&KeywordSearch=$esckeyword&" ."mode=$category&type=$type&page=1$xsort&f=xml&locale=jp" ."$jphack"; my $s = Net::HTTP::NB->new(Host => $host) || die $@; $s->write_request(GET => $resource); my $sel = IO::Select->new($s); READ_HEADER: { die "Header timeout" unless $sel->can_read(10); my($code, $mess, %h) = $s->read_response_headers; redo READ_HEADER unless $code; } my $xmlresp = ''; while (1) { die "Body timeout" unless $sel->can_read(10); my $buf; my $n = $s->read_entity_body($buf, 1024); last unless $n; $xmlresp .= $buf; } my @xmlresp = split /\n/, $xmlresp; my $x = 0; my $r = ''; foreach my $i (@xmlresp) { $x++; # Hack: Replace invalid UTF-8 encoded Japanese Yen Symbol with # another representation (0xa5 → "¥"). $i =~ s!<(\w+)Price>(\xA5)(.*)</(\w+)Price>!<$1Price>¥$3</$4Price>!; $r .= "$i\n"; } return $r; }
たぶん、まだ続くよ (このページって、期せずして「Google ホイホイ」化している? うちのページは Google ランク高いみたいなので、 あまりうかつなこと書けないんだが ^^;)。
この話題、戻る← 2003/07/22 『AWS: 日本語キーワード検索文字化け』
この話題、続く→ 2003/07/23 『AWS: 微妙に改造』