てきとーなamazon検索


require "open-uri"
require "rexml/document"
require "uri"

module AWSECommerceServiceItemSearch

def camelize(underscored)
if /^[a-z]+(_[a-z]+)*=?$/ =~ underscored
underscored.sub(/^(.)/) { $1.upcase }.gsub(/_(.)/) { $1.upcase }
else
underscored
end
end

module_function :camelize

class Request
@@base_url = "http://webservices.amazon.co.jp/onca/xml"

def initialize(id)
@params = {}
self.service = "AWSECommerceService"
self.operation = "ItemSearch"
self.AWSAccessKeyId = id
end

def search
res = nil
open(request_url) {|f| res = Response.new(f.read)}
return res
end

def request_url
@@base_url + "?" + query_string
end

def query_string
@params.collect {|param, value| param + "=" + value}.join("&")
end

def method_missing(name, *args)
param = AWSECommerceServiceItemSearch::camelize(name.to_s)

if /=$/ =~ param
@params[param.chop] = URI.encode(args.join(","))
else
@params[param]
end
end
end

class Response
def initialize(source)
@root = (source.is_a? REXML::Element) ? source : REXML::Document.new(source).root
end

def [](name)
path = AWSECommerceServiceItemSearch::camelize(name.to_s)
elems = @root.get_elements(path)
elems.collect {|elem| Response.new(elem)}
end

def method_missing(name, *args, &block)
path = AWSECommerceServiceItemSearch::camelize(name.to_s)
elem = @root.elements[path]
elem ? Response.new(elem) : @root.send(name, *args, &block)
end
end

end

実行はこんな感じ。


s = AWSECommerceServiceItemSearch::Request.new("...")
s.search_index = "Books"
s.keywords = "Ruby"

s.search.items[:item].each {|i|
puts i.item_attributes.title.text
}

追記
camelizeはあんまよくないかも。統一感のないAPIになるし。