AmazonECS4.0 対応ASIN Search

ちょっと作ってみたので公開してみる。
公開しておけばなんかの参考にはなるだろうか

require "open-uri"
require 'rexml/sax2parser'
require 'cgi'


class AmazonECS
attr_accessor :associate_id,:subscription_id,:output_xml
def initialize()
  @output_xml = nil
end
def asinSearch(asin)
  xml = ""
  open(makeASINSearchURL(asin)) { |f|
    while buf = f.read(4096)
      xml << buf
    end
  }
  if @output_xml then
    File.open(@output_xml,"w") { |f|
      f << xml
    }
  end
  parseResponse(xml)
end

def makeASINSearchURL(asin)
  token = ""
  search_token = asin
    asin.each{ |id|
    token << id << ","
  }
  %Q[http://webservices.amazon.co.jp/onca/xml?Service=AWSECommerceService&SubscriptionId=#{@subscription_id}&AssociateTag=#{@associate_id}&Operation=ItemLookup&ResponseGroup=Medium&ContentType=text/xml&IdType=ASIN&ItemId=#{token}]
end
def makeAuthorSearchURL(author,page=1)
   author = CGI.escape(author)
   %Q[http://webservices.amazon.co.jp/onca/xml?Service=AWSECommerceService&SubscriptionId=#{@subscription_id}&AssociateTag=#{@associate_id}&Operation=ItemSearch&ResponseGroup=Medium&ContentType=text/xml&SearchIndex=Books&Author=#{author}&Page=#{page}]
end

def parseResponse(xml)
  parser = REXML::SAX2Parser.new( xml )
  errors = []
  path = []
  args = []
  ret = []
  parser.listen( :start_element) {|uri, localname, qname, attributes|
    path.push({:name=>localname,:attr=>attributes}) 
    case localname
    when "Error"
      errors.push({})
    when "Argument"
      args.push({:name=>attributes["Name"],:value=>attributes["Value"]})
    when "Item"
      print "Item"
      ret.push({})
    end
  }
  parser.listen( :end_element) {|uri, localname, qname|
    path.pop
  }
  parser.listen( :characters){|text|
    elmname = path.last[:name]
    case elmname
    when "Code","Message"
      errors.last[elmname] = text if path[-2][:name] == "Error"
    when "ASIN","DetailPageURL" 
      ret.last[elmname] = text if path[-2][:name] == "Item"
    when "Title","PublicationDate","ReleaseDate","Publisher","ProductGroup","Studio","Label"
      ret.last[elmname] = text if path[-2][:name] == "ItemAttributes"
    when "Author","Artist"
      if  path[-2][:name] == "ItemAttributes" then
        ret.last[elmname] = [] unless ret.last[elmname] 
        ret.last[elmname].push(text)
      end
    when "Creator"
      if  path[-2][:name] == "ItemAttributes" then
	      ret.last["Creator"] = [] unless ret.last["Creator"] 
  	    ret.last["Creator"].push({"name"=>text,"role"=>path.last[:attr]["Role"]})
  	  end
    when "URL"
      imagename = path[-2][:name]
      case imagename
      when "SmallImage","MediumImage","LargeImage"
        ret.last[imagename] = text
      end
    end
  
  }
  parser.parse
  return ret,errors,args
end


end


aws = AmazonECS.new
aws.output_xml = "/tmp/result.xml"
aws.associate_id = "moleskindiary-22"
aws.subscription_id = "1662RT4B1C0H8X4PP382"


ret,errors,args = aws.asinSearch(%w{9999999999 B0006D3GPM B0002MOL1A 4047136468 B000232BMK 4061496468 4003360125})


print "result\n"
ret.each {|item|
  item.each {|key,data|
  print key,"=",data,"\n"
  }
}
print "error\n"
errors.each {|item|
  item.each {|key,data|
  print key,"=",data,"\n"
  }
  
}
print "args\n"
args.each {|item|
  item.each {|key,data|
  print key,"=",data,"\n"
  }
  
}

注意すべき点

ECS4.0を利用するにはDevelopers TokenじゃなくてSubscription idが必要です。

このガイドにあるサンプルリクエストを試してみるためには、Amazon Web サービスの登録IDを以下のURLから取得する必要があります。http://www.amazon.com/gp/aws/registration/registration-form.html

ECS4.0はSmallなどImageがない場合、SmallImageなどのタグ自体が返ってきません。(3.0だとサイズ1の画像が帰ってくるんだっけ?)

レスポンスでどんなタグが帰ってくるかはTry&Errorで研究してやってみないとわかりません。

参考URL

ECS 3.0 から 4.0 への移行
http://aws.typepad.com/aws_jp/2004/11/ecs_30_40.html
Amazon ECS 4.0 解説1 RESTリクエストのパラメータ
http://www.goodpic.com/mt/archives2/2004/10/amazon_ecs_401.html