AmazonAPI Pythonによるxmlデータの取得

以前Amazonのデータを取得するAPIの登録方法を紹介しました。
Amazon Product Advertising API 登録の流れ - 備忘録


今回は実際にPythonによってデータをxml形式で取得し、xmlパースを行うことによって欲しい形式に変換する手順を追ってみましょう。

AmazonAPIに登録してIDやKeyを取得すること前提ですので、先に上の登録を終えてから読んで下さい。
また、AmazonAPIはよく仕様が変わっているようですので、2015年1月以降は細部が異なる可能性があります。


さて、xmlの解析を行う前に、まずはxmlがどういう流れで得られるのか確認します。

AmazonAPIというディレクトリを作っておきます。
そこに、以下のPythonコードをamazon.pyとして保存して下さい。
これが無いと何も実践できないため先に導入しましたが、意味を解読するためには最後まで読んだ後に戻ってきたほうがよいため、ここは作業と思って下さい。

#coding:utf-8
import urllib2
import hashlib, hmac
import base64
import time

class Amazon:
	def __init__(self, access_key, secret_access_key, associate_tag=None):
		self.amazonurl = "http://webservices.amazon.co.jp/onca/xml"
		self.proxy_host = None
		self.proxy_port = None
		self.access_key = access_key
		self.secret_access_key = secret_access_key
		self.associate_tag = associate_tag
		self.version = "2009-10-01"
		self.url = None

	def setProxy(self, host, port=8080):
		self.proxy_host = host
		self.proxy_port = port

	def setVersion(self, version):
		self.version = version

	def itemLookup(self, item_id, **options):
		params = options
		params["Operation"] = "ItemLookup"
		params["ItemId"] = item_id
		return self.sendRequest(params)

	def itemSearch(self, search_index, **options):
		params = options
		params["Operation"] = "ItemSearch"
		params["SearchIndex"] = search_index
		return self.sendRequest(params)

	def buildURL(self, params):
		params["Service"] = "AWSECommerceService"
		params["AWSAccessKeyId"] = self.access_key
		if self.associate_tag is not None:
			params["AssociateTag"] = self.associate_tag
		params["Timestamp"] = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
		sorted_params = sorted(params.items())

		request = []
		for p in sorted_params:
			pair = "%s=%s" % (p[0], urllib2.quote(p[1].encode("utf-8")))
			request.append(pair)

		msg = "GET\nwebservices.amazon.co.jp\n/onca/xml\n%s" % ("&".join(request))
		hmac_digest = hmac.new(self.secret_access_key, msg, hashlib.sha256).digest()
		base64_encoded = base64.b64encode(hmac_digest)
		signature = urllib2.quote(base64_encoded)

		request.append("Signature=%s" % signature)
		url = self.amazonurl + "?" + "&".join(request)

		return url

	def sendRequest(self, params):
		self.url = self.buildURL(params)
		if self.proxy_host:
			proxy_handler = urllib2.ProxyHandler({"http":"http://%s:%s/" % (self.proxy_host, self.proxy_port)})
			opener = urllib2.build_opener(proxy_handler)
		else:
			opener = urllib2.build_opener()
		return opener.open(self.url).read()

こちらのサイトから引用させて頂きました。


続いて、先ほどのソースコードと同じAmazonAPIディレクトリにamazon_search.pyとして次のファイルを置きます。

#coding:utf-8
import amazon import Amazon

access_key_id=""
secret_access_key=""
associate_tag=""

amazon=Amazon(access_key_id,secret_access_key,associate_tag)
xml=amazon.itemSearch("Books",Keywords=u"数学",ItemPage="1",ResponseGroup="Large")
print amazon.url

access_key_id、secret_access_key、associate_tagには自分のものを代入してください。
実行すると、print amazon.urlの出力としてURLが得られるはずなので、それをブラウザで見てみましょう。
f:id:alstd:20150102023029p:plain
xmlが確かに得られています。

amazon_search.py内の

xml=amazon.itemSearch("Books",Keywords=u"数学",ItemPage="1",ResponseGroup="Large")

という記述通り、数学に関する本を1検索分(=10冊分)、詳細なデータ(=Large)で得られています。


AmazonとPC間の情報のやりとりはたったこれだけで終わりです。

もちろん、検索の関数としてitemSearch以外にもありますし、オプションもResponseGroupの属性として山ほどあります。
ただし、これらは固有名詞的なものなので覚えてもあまり意味がないですし、Amazon公式マニュアルを参考にしましょう。


その後はxmlパースに移ります。
区切りがよいので次回に回します。
Amazonクラスに関する説明も、仕様が変わったり、他のAPIにも応用する上では必要なので、いずれ説明する予定です。