PythonのlxmlでAmazonAPIを使ってみた

AmazonAPIを使用するには、
Amazon Web Services へ申し込まなければならない。

から申し込んでアカウントを作成する。
そうするとメールが来るので、
ログインすると画面右下に自分の「Your Access Key ID」が表示される。

AmazonAPIを使用するための設定

URL Amazon.co.jp http://webservices.amazon.co.jp/onca/xml?
Amazon.com http://webservices.amazon.com/onca/xml?
SubscriptionId アソシエイトID Amazon Web Servicesで取得したYour Access Key ID
Operation ItemSearch 商品名、著者名などで検索
ItemLookup ASINなどのItemIdで、商品を検索
ResponseGroup 取得したい情報(カンマで複数指出来る 「Small : 少ない情報」など他にも多数ある。 例:ResponseGroup=Small,Offers,Images
Page ページ番号 デフォルトは「1」

※ ResponseGroupに関しては、 http://wiki.makotokw.com/index.php?cmd=read&page=Memo%2FAmazon%20API を参考にすると解りやすい。

Pythonで必要なライブラリを読み込み。 今回は、urllib2 と lxmlのetreeです。

# まず必要なライブラリを読み込む
>>> import urllib2
>>> from lxml import etree

次にAmazonAPIを使用するのに必要なリクエスト先の設定。 今回は画像や少ない情報などを取得してみる。

# 解りやすいように各パラメータを分けて設定
>>> host = u'http://webservices.amazon.co.jp/onca/xml?Service=AWSECommerceService'
>>> id = u'&SubscriptionId=アソシエイトID'
>>> ope = u'&Operation=ItemSearch'
>>> res = u'&ResponseGroup=Small,Offers,Images'

# 上記に検索したい値やページ数を設定する
(今回はサンプルでキーワードは「nujabes」種類は「Music」ページは「1」)

>>> keyword = u'nujabes'
>>> keyword = u'&Keywords=' + quote(keyword.encode('utf-8'))
>>> page = u'&Page=1'
>>> index = u'&SearchIndex=Music'

これらをつなげて一つのURLにする。

>>> url = host+id+ope+res+index+page+keyword
>>> xml = urllib2.urlopen(url).read()
>>> root = etree.fromstring(xml, parser=etree.XMLParser())
>>> root
<Element {http://webservices.amazon.com/AWSECommerceService/2005-10-05}ItemSearchResponse

取れてるので、xpathで指定して必要なものを取得する。
lxmlのネームスペースではまったが、
http://humming.via-kitchen.com/2007/12/25/namespace-trap-on-xpath/
に書かれていた。
Thanks Hige

# 順番にxpathで取得出来ているか確認
>>> root.xpath('./n:Items',
namespaces={'n':'http://webservices.amazon.com/AWSECommerceService/2005-10-05'})
<Element {http://webservices.amazon.com/AWSECommerceService/2005-10-05}Items at 95185f4>]
>>> root.xpath('./n:Items/n:TotalResults',
namespaces={'n':'http://webservices.amazon.com/AWSECommerceService/2005-10-05'})
<Element {http://webservices.amazon.com/AWSECommerceService/2005-10-05}TotalResults at 9518734>]

取れているので、実際に取得してみる。

>>> root.xpath('./n:Items/n:TotalResults/text()',
namespaces={'n':'http://webservices.amazon.com/AWSECommerceService/2005-10-05'})
['16']

ヒットしたのが16件なのが解る。
次に画像のパスを取得してみる。

>>> root.xpath('./n:Items/n:Item/n:SmallImage/n:URL/text()',
namespaces={'n':'http://webservices.amazon.com/AWSECommerceService/2005-10-05'})
['http://ecx.images-amazon.com/images/I/111P48yiM0L.jpg',
 'http://ecx.images-amazon.com/images/I/11YVKR670PL.jpg',
 'http://ecx.images-amazon.com/images/I/1152KJWFCVL.jpg',
 'http://ecx.images-amazon.com/images/I/11Gho2a1umL.jpg',
 'http://ecx.images-amazon.com/images/I/11MC%2BTzFbYL.jpg',
 'http://ecx.images-amazon.com/images/I/01NrqSIQhOL.jpg',
 'http://ecx.images-amazon.com/images/I/11WDQB96Y6L.jpg',
 'http://ecx.images-amazon.com/images/I/01KT1Y6ZQ3L.jpg',
 'http://ecx.images-amazon.com/images/I/11Y42HBV18L.jpg',
 'http://ecx.images-amazon.com/images/I/112xsBHMa7L.jpg']

取れてるね。

# ここから実際に必要な情報を取得する。

>>> asin = root.xpath('./n:Items/n:Item/n:ASIN/text()',
namespaces={'n':'http://webservices.amazon.com/AWSECommerceService/2005-10-05'})
>>> title = root.xpath('./n:Items/n:Item/n:ItemAttributes/n:Title/text()',
namespaces={'n':'http://webservices.amazon.com/AWSECommerceService/2005-10-05'})
>>> page_url = root.xpath('./n:Items/n:Item/n:DetailPageURL/text()',
namespaces={'n':'http://webservices.amazon.com/AWSECommerceService/2005-10-05'})
>>> img_url = root.xpath('./n:Items/n:Item/n:SmallImage/n:URL/text()',
namespaces={'n':'http://webservices.amazon.com/AWSECommerceService/2005-10-05'})
>>> height = root.xpath('./n:Items/n:Item/n:SmallImage/n:Height/text()',
namespaces={'n':'http://webservices.amazon.com/AWSECommerceService/2005-10-05'})
>>> width = root.xpath('./n:Items/n:Item/n:SmallImage/n:Width/text()',
namespaces={'n':'http://webservices.amazon.com/AWSECommerceService/2005-10-05'})

取得しようとしているのは、
ASIN、TITLE、ページのURL、画像のURL、画像の高さ、画像の幅
これらの値を各ディクショナリとして突っ込む。
今回はmapを使って処理してみた。
もっと良い方法があれば是非教えて欲しいなぁ〜。

>>> def catstr(asin, title, page_url, img_url, height, width):
>>>     list = {}
>>>     list = {
...             'asin' : asin,
...             'title' : title,
...             'page_url' : page_url,
...             'img_url' : img_url,
...             'height' : height,
...             'width' : width,
...         }
...         return list
...
>>> list = map(catstr, asin, title, page_url, img_url, height, width)
>>> print list