ラベル Amazon の投稿を表示しています。 すべての投稿を表示
ラベル Amazon の投稿を表示しています。 すべての投稿を表示

11/03/2011

amazon/ecs rubyでISBNを検索する(改訂版)

以前のエントリ「 rubyでISBNを検索する (2009/10/17)」で作ったスクリプトが、昨日から動かなくなった。そう言えば、Amazonから何か連絡が来ていたような気がする。あわてて検索すると、確かに、
重要:アマゾンProduct Advertising APIの仕様変更について
(途中略)
全てのAPIへのリクエストにおいて、AssociateTagが必須パラメータとなり、リクエスト処理時の確認対象となります。
(以下略)
となっている。
仕方が無いので、リクエストにAssosicate Tagを追加して送るように書き換えてみたが、動かない。同時に、検索結果として戻って来るxml (WSDL)の体系も変更になったようだ。それも書き換えて、さあどうだ!と思ったが、今度は検索結果が文字化けしている。
(2012年6月29日追記:amazon/ecsの最新バージョン(2.2.4)では、文字化けは解消されている)

いろいろググったあげく、使っているモジュール(amazon/ecs)の一部を直に書き換えれば対応できることが分かった。(ここに辿り着くまで約1日)
備忘のために、手順を記しておく。

  1. githubからamazon/ecsのソース(ecs.rb)をダウンロードし、保存
  2.  ecs.rbの141行目を書き換え
    @doc = Nokogiri::XML(xml)
     ↓
    @doc = Nokogiri::XML(xml, nul, 'UTF-8')
  3. オリジナルのスクリプトに記載しているrequire文もそれに合わせ修正

(2011年11月13日追記)
予想外に何件かのアクセスがあったので、簡単なソースを紹介。スクリプト名は"test.rb"。

require 'rubygems'
require 'amazon/ecs'

# パラメータ設定( associate tag, access key, secret key)
Amazon::Ecs.options = {
 :associate_tag => '[your associate tag]',
 :AWS_access_key_id => '[your developer token]',       
 :AWS_secret_key => '[your secret access key]'
}

# amazon-ecsの呼び出し
# ruby スクリプト名 ISBNの形式で実行する
#(ARGV[0]にはISBNが入る)
res = Amazon::Ecs.item_search(
        ARGV[0],
        {:search_index => 'Books', 
         :response_group => 'Medium',
          :country => 'jp'})

#結果の表示(著者名等は適宜追加)
res.items.each do |item|
    print "ASIN= ", item.get('ASIN'), "\n"
    print "Title= ",   item.get('ItemAttributes/Title'), "\n"
end


結果:
$ ruby test.rb 9784101181066
ASIN= 4101181063
Title= マキアヴェッリ語録 (新潮文庫)

10/17/2009

rubyでISBNを検索する

内容が古くなったので改訂版を投稿しました。

=====

読んだ本のリストを作っているが、ISBNから書名や、著者、出版社の情報を取りたい。AmazonのAWSに入っているので、rubyを使ってやってみようと思った。

一年程前に、一定のURLでリクエストすると、xmlで情報が帰って来たので、これでやろうと思った。でもどういう訳か出来ない! どうやら、APIの仕様が変わり、timestampやら電子署名を追加して送らなくてはならないようだ。Amazonの"Signed Requests Helper"と言うサイトがあって、Access KeyとSecret Keyを入れれば、URLを作ってくれるサイトはあるのだが、これでははかどらない。仕方がないので、ググった結果、ruby-awsを使うことにした。

まず、ruby-awsのインストール。普通は、gem install ruby-awsで出来るはずなのだが、どうしても私の環境ではうまくいかない。(Mac OSX Snow Leopard, ruby 1.8.7, gem 1.3.1)
やむを得ず、ruby-awsのサイトからダウンロードし、直接、インストールをしてみた。

ダウンロードして、解凍後、ruby-aws-0.7.0の中にある、setup.rbを実行する。(INSTALLファイルを参照)
$ ruby setup.rb config
$ ruby setup.rb setup
# ruby setup.rb install

("#"のところは、ルート権限が必要な場合、sudo ruby setup.rb install)
次に、configファイルを作成。ユーザーのhomeで、下記の内容のファイルを作り、名前を".amazonrc"として保存。
[global]
key_id        = 'アクセスキー'
secret_key_id = 'アクセスの秘密キー'
 associate     = 'アソシエートのコード'
locale        = jp
cache         = true
cache_dir     = .

rubyのスクリプト(amazon_isbn.rb)は、こんな感じ。(エラー発生時の処理は書いていない)
require 'amazon/aws'
require 'amazon/aws/search'

isbn = ARGV.shift   # 引数にISBNを入れる

# 設定ファイルのデフォルトは /etc/amazonrc か ~/.amazonrc
ENV['AMAZONRCDIR']  = '.' # 設定ファイルの位置を変えるときはこれ

begin

il = Amazon::AWS::ItemLookup.new('ISBN',{'ItemId' => isbn,'SearchIndex' => 'Books'})
rg = Amazon::AWS::ResponseGroup.new( 'Medium' )
req = Amazon::AWS::Search::Request.new()
page = req.search(il, rg)

print "ASIN = ",           page.item_lookup_response.items.item.asin ,"\n"
print "title = ",          page.item_lookup_response.items.item.item_attributes.title,"\n"
print "publisher = ",      page.item_lookup_response.items.item.item_attributes.publisher,"\n"
print "author = ",         page.item_lookup_response.items.item.item_attributes.author,"\n"

rescue SocketError => exp
# ソケットエラーが出た場合は10秒待ってから、beginより再実行
print exp.backtrace ,"\n  [", exp.message , "]\n"
sleep 10
retry
rescue => exp
print exp.backtrace ,"\n class=", exp.class , "\n  [", exp.message , "]\n"
end


これで、例えばISBNコードが"4766924584"の書名、出版社、著者を引きたい時は、

$ ruby amazon_isbn.rb 4766924584
=>
ASIN = 4766924584
title = やっぱり北海道だべさ!!—内地の人にはわかんないっしょ
publisher = 勁文社
author = 千石 涼太郎

と、結果が帰ってくる。
あとは、ISBNのリストを連続して、読み込み、テキストにはき出すところを書けば完成か。

次の二つのブログを参考にさせていただきました。ありがとうございます。