SOAP4RでAmazon Web Service

SOAP4Rを使ってAmazon Web Serviceを利用したときのメモ。 あんまり実がないなあ。

SOAP4RでAWS

Amazon Hacks 世界最大のショッピングサイト完全活用テクニック100選

Amazonの提供してくれるWeb Service - AWSを使って、商品を検索したり 書籍情報を取り出してみました。 AWSではXML-RPCやSOAPなど複数のインターフェイスを提供しています。 今回はNaHiさんのSOAP4Rを使って楽をしちゃいました。

手順

Tokenの入手

AWSのサービスを利用するには、デベロッパー・トークンが必要です。 次のページが参考になります。

<URL:http://www.amazon.co.jp/exec/obidos/subst/associates/join/webservices.html>

このページに出てるけど、SDKをダウンロード、Tokenを取得してアプリを書きます。

  1. SDKをダウンロード - ドキュメントが入ってます。英語。
  2. Tokenの取得 - やはり英語のページです。
  3. アプリケーションの開発

アソシエイト・プログラムへの参加は必須でないようですね。 私はアソシエイトの参加してたのでそのIDを使うことにしました。

SOAP4Rの準備

RAAからSOAP4Rをダウンロードします。 このページを書いている現在(2004-09-05)のバージョンは1.5.2のようです。

私はruby-1.8系ブランチの先端を使用しています *1 が、SOAP4Rライブラリ自体は1.5.2と同様なようです。

しかしWSDLからRubyのクラスを生成してくれるwsdl2ruby.rbは rubyのアーカイブに含まれていません。 RAAからダウンロードしたSOAP4Rからwsdl2ruby.rbを取り出して適切な *2に置いて実行権を設定します。

ruby-1.8.0を使っているならSOAP4Rのライブラリもインストールした方が いいのかも。(実験できないからわからないです。ごめん)

wsdl2rubyによるクラス定義の生成

SDKのドキュメントにWSDLのURLが載っています。 wsdl2ruby.rbにそのURLを渡してRubyのクラス定義を生成してもらいましょう。

% wsdl2ruby.rb --wsdl http://soap.amazon.com/schemas3/AmazonWebServices.wsdl --classdef --force

AmazonSearch.rbというファイルができましたか? きっとできたと思います。

中を見るとアクセサがたくさん定義されています。 XSDLを自分で読むことに比べたらwsd2rubyの生成するRubyスクリプトを眺める方が簡単です。 クエリの結果の仕様をドキュメントから探すよりもこのスクリプトを調べる方が速そうな気がします。

proxy

proxy経由で試すには次の設定が必要みたい。

SOAP_USE_PROXY=on
HTTP_PROXY=http://foo.bar:port

実験

こんなのを書いて実験してみました。 書籍をキーワードで検索して結果を表示するスクリプトです。 www.amazon.comではなくwww.amazon.co.jpを利用します。

# aws0.rb
require 'soap/wsdlDriver'
require 'AmazonSearch.rb'

class AmazonWebService
  def initialize(tag = 'ilikeruby-22')
    @devtag = get_devtag
    @tag = tag
    @amazon = SOAP::WSDLDriverFactory.new(wsdl).createDriver
    @amazon.generate_explicit_type = true
  end
  attr_reader :amazon

  def locale
    nil
  end

  def wsdl
    'http://soap.amazon.com/schemas3/AmazonWebServices.wsdl'
  end

  def keyword_search(text)
    req = KeywordRequest.new(text, '1', 'book', @tag, "lite", @devtag)
    req.locale = locale if locale
    @amazon.KeywordSearchRequest(req).Details
  end

  private
  def get_devtag
    File.open(File.expand_path("~/.amazon_key")) do |fp|
      return fp.read.chomp
    end
  end
end

class AmazonCoJp < AmazonWebService
  def locale
    'jp'
  end

  def wsdl
    'http://soap.amazon.co.jp/schemas3/AmazonWebServices.wsdl'
  end
end

if __FILE__ == $0
  def show_item(item)
    puts "== #{item.ProductName}"
    puts "* asin: #{item.Asin}"
    puts "* manufacturer: #{item.Manufacturer}"
  end

  $amazon = AmazonCoJp.new
  while line = gets
    begin
      keyword = line.chomp
      $amazon.keyword_search(keyword).each do |item|
        show_item(item)
      end
    rescue
      p $!
    end
  end
end

実行するときはrubyに適切な文字コードを指定してください。 例えばでUTF-8で表示している端末の場合には-Ku、 EUCなら-Keなどです。

% ruby -Ku aws0.rb
druby                   ← 入力する
== dRubyによる分散オブジェクトプログラミング
* asin: 4756139612
* manufacturer: アスキー
ruby way                ← 入力する
== The Ruby Way?Ruby道への招待
* asin: 4798102288
* manufacturer: 翔泳社

文字コードによって適切な変換をしてくれるのはSOAP4Rかなあ。便利だ。

wsdl2rubyで生成したクラスのメソッドはCamelCaseなので注意。 少しびっくりします。 実際のアプリケーションでは一段ラップするクラスをおくのかなあ。

応用

これを利用してRWikiを拡張してみました。 このサイト(I like Ruby)もSOAP4R経由でAWSを利用して作られています。

この話の続きはThe RWikiで(ほんとう?)


*11.9や1.8.0の状況はちょっとわかりません。
*2私は/usr/local/bin/