プログラマでありたい

おっさんになっても、プログラマでありつづけたい

RubyでAmazon Product Advertising APIを再び使ってみる

 ちょっと必要になって、再びAmazonのProduct Advertising APIを触ってみました。このAPIは、Amazon謹製のAPIで、商品検索や個別商品情報の取得が出来ます。元々このAPIの名前は、Amazon アソシエイト Web サービスといって、AWSと呼ばれていました。クラウドの方のAWSが出る前の話ですね。その後、クラウドの方がAWSという名称になり、こちらのAPIの名前がProduct Advertising APIに変わっています。
 ちなみに、Amazon Web サービスというサービス名は、現在もクラウドのAWS単体を指すのではなく、AmazonがAPIを使って提供しているサービス全体を指す言葉のようですね。ややこしいけど、全く必要としない豆知識でした。

Product Advertising APIを操作するRuby Gemを選ぶ



 Product Advertising APIは、過去の名称のものも含めて何度かメジャーバージョンアップしています。そして、古いバージョンのものは、一定期間後に使えなくなり気がついていないアプリ開発者の大絶滅を繰り返しているという歴史があったと思います。そんな理由があるので、古いライブラリが打ち捨てられることも多く、イマイチどのライブラリがメジャーなのか解りづらいところです。
 そんな中でGitHubをサクッと検索してみると、上位にくるのは下記の3つです。

  1. GitHub - jugend/amazon-ecs: Amazon Product Advertising Ruby API
  2. GitHub - completelynovel/amazon-product-advertising-api: A nice rubyish interface to the Amazon Product Advertising API, formerly known as the Associates Web Service and before that the Amazon E-Commerce Service.
  3. GitHub - hakanensari/vacuum: Amazon Product Advertising API client


 1つ目のAmazon ECSについては、5年前に記事を書いた時点から生き残っている古株です。その割には、最近でもメンテナンスされています。2つ目のAmazon Product Advertising APIについては、その名もズバリの名前でええのかよという感じですが、もうメンテナンスされていません。最後のvacuumについては、何でその名前を選んだという名称です。作り自体は、Product Advertising APIの薄いラッパーで手軽で使いやすいです。作られたのも最近で、比較的メンテナンスされています。上手くいけば、ちょっと複雑化しているAmazon ECSの対抗馬になると思いますが、名前からAmazon関係のライブラリと気が付かれることもないので、メジャーになりにくいのではと思います。

 そんな訳で、またAmazon ECSを利用します。インストールは、Gemで一発です。

$ gem install amazon-ecs
Fetching: amazon-ecs-2.2.5.gem (100%)
Successfully installed amazon-ecs-2.2.5
Parsing documentation for amazon-ecs-2.2.5
Installing ri documentation for amazon-ecs-2.2.5
Done installing documentation for amazon-ecs after 0 seconds
1 gem installed

Amazon ECSでProduct Advertising APIを操作する



 Product Advertising APIのサインアップがされているという前提で、アクセス・キーとシークレット・アクセス・キーは取得済みの前提とします。ちなみに、これらのキーは、AWSのマスターキーと同じで、かつProduct Advertising APIはIAMアカウントで操作できません。結構危険なので、両方使う人は別のアカウントを作る方がよいでしょうね。
 さて、下記のプログラムが、Amazon ECSを利用して一覧検索と個別商品取得をした例です。基本的には、item_searchメソッドとitem_lookupを覚えていれば事足ります。あとは、レスポンスをppなりで確認しながら弄れば大丈夫でしょう。

require 'amazon/ecs'
require 'pp'

Amazon::Ecs.options = {
  :associate_tag => 'sampleapp-22', 
  :AWS_access_key_id => ENV['AWS_ACCESS_KEY'], 
  :AWS_secret_key => ENV['AWS_SECRET_ACCESS_KEY']
}

#商品検索
res = Amazon::Ecs.item_search('ruby', :country => 'jp')
res.items.each do |item|
  puts item.get('ItemAttributes/Title')
end

#個別商品の詳細表示
res = Amazon::Ecs.item_lookup('B00JXEFT6Y', :response_group => 'Small, ItemAttributes, Images', :country => 'jp')
pp res


## 商品検索 item_searchメソッド
 商品検索のメソッドの実装は以下のとおりです。思いのほか、シンプルです。まぁ基本的には、Amazon Product Advertising APIに値を送っているだけです。optsに何を渡すかは、APIの方を見ないと解りません。

    # Search amazon items with search terms. Default search index option is 'Books'.
    # For other search type other than keywords, please specify :type => [search type param name].
    def self.item_search(terms, opts = {})
      opts[:operation] = 'ItemSearch'
      opts[:search_index] = opts[:search_index] || 'Books'
      
      type = opts.delete(:type)
      if type 
        opts[type.to_sym] = terms
      else 
        opts[:keywords] = terms
      end
      
      self.send_request(opts)
    end

 まずOperationですが、このメソッドを利用すると勝手にItemSearchが指定されます。このAmazon ECSは、幾つかあるAPIのOperationのうちで、3つだけ実装しています。ItemLookupとItemSearch,BrowseNodeLookupです。APIには、下記の通り9つの機能が幾つかあります。商品検索系とカート系の機能ですね。
http://docs.aws.amazon.com/AWSECommerceService/latest/DG/CHAP_OperationListAlphabetical.html

  • BrowseNodeLookup
  • CartAdd
  • CartClear
  • CartCreate
  • CartGet
  • CartModify
  • ItemLookup
  • ItemSearch
  • SimilarityLookup

 ItemSearchのAPIの仕様は以下のURLのとおりです。
http://docs.aws.amazon.com/AWSECommerceService/latest/DG/ItemSearch.html
オプションの値を、ハッシュ配列に格納して送ることが可能です。例えば、著者指定で検索する例です。

opts = {
  :country => 'jp',
  :author => '北方謙三'
}
res = Amazon::Ecs.item_search('三国志', opts)
res.items.each do |item|
  puts item.get('ItemAttributes/Title')
end


## 商品取得 item_lookupメソッド
 個別商品の取得は、item_lookupメソッドを利用します。商品を一意に識別するために、ASIN(本の場合だと、ISBN)を利用します。
http://docs.aws.amazon.com/AWSECommerceService/latest/DG/ItemLookup.html

# Search an item by ASIN no.
def self.item_lookup(item_id, opts = {})
  opts[:operation] = 'ItemLookup'
  opts[:item_id] = item_id
    
  self.send_request(opts)
end    


## その他のOperationの利用
 Amazon ECSで実装されている以外の、Operationを利用する場合は、send_requestメソッドを利用します。Optionの値を詰め込んで、send_requestメソッドを呼び出します。send_requestメソッドの中身が何をやっているかと、タイムスタンプを付けて、リクエスト用のURLに変換して送ってくれています。まぁ、それだけやってくれれば充分だなぁという作りです。カートなども、これを使えば実装できます。

    # Generic send request to ECS REST service. You have to specify the :operation parameter.
    def self.send_request(opts)
      opts = self.options.merge(opts) if self.options
      
      # Include other required options
      opts[:timestamp] = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ")

      request_url = prepare_url(opts)
      log "Request URL: #{request_url}"
      
      res = Net::HTTP.get_response(URI::parse(request_url))
      unless res.kind_of? Net::HTTPSuccess
        raise Amazon::RequestError, "HTTP Response: #{res.code} #{res.message}"
      end
      Response.new(res.body)
    end


## まとめ
 商品の情報をまとめて取得しようと、久々に使ってみました。やはりAmazonはAPIがしっかり設計されているので使いやすいですね。


See Also:
RailsでProduct Advertising APIを扱うAmazon ECSを使う


参照:
http://docs.aws.amazon.com/AWSECommerceService/latest/DG/Welcome.html