Search

[Python] I Tried the Amazon Product Advertising API

Tadashi Shigeoka · Wed, August 24, 2011

I tried the Amazon Product Advertising API in Python.

Python

You need to sign up for AWS to use the Amazon API.

The site below publishes Python code for calling the Amazon API. It also covers how to build the authentication signature, so it’s very useful.

・Source: PythonでAmazon Product Advertising APIを使う - 人工知能に関する断想録

amazon.py (code taken directly from the source site)

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

"""
Fetch product information via the Amazon Product Advertising API
"""

class Amazon:
    def __init__(self, access_key, secret_access_key, associate_tag=None):
        """Constructor"""
        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):
        """Set a proxy"""
        self.proxy_host = host
        self.proxy_port = port
    
    def setVersion(self, version):
        """Set the API version"""
        self.version = version
    
    def itemLookup(self, item_id, **options):
        """Fetch item details"""
        params = options
        params["Operation"] = "ItemLookup"
        params["ItemId"] = item_id
        return self.sendRequest(params)
    
    def itemSearch(self, search_index, **options):
        """Search for items"""
        params = options
        params["Operation"] = "ItemSearch"
        params["SearchIndex"] = search_index
        return self.sendRequest(params)
    
    def buildURL(self, params):
        """Build the REST request URL"""
        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())
        
        # Expand the params hash
        request = []
        for p in sorted_params:
            pair = "%s=%s" % (p[0], urllib2.quote(p[1].encode("utf-8")))
            request.append(pair)
        
        # Signed requests are required since 2009/8/15
        # Compute HMAC-SHA256 with the Secret Access Key
        msg = "GET\
webservices.amazon.co.jp\
/onca/xml\
%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)
        
        # Append Signature to the request to build the final URL
        request.append("Signature=%s" % signature)
        url = self.amazonurl + "?" + "&".join(request)
        
        return url
        
    def sendRequest(self, params):
        """Send the request to Amazon and return the XML response"""
        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()

I tried searching books by keyword.

Below is the code, based on the source site, adjusted so that it can be run in Python’s interactive mode with the character-encoding issue resolved.

#coding:utf-8
import sys, codecs
sys.stdout = codecs.lookup('utf_8')[-1](sys.stdout)

from amazon import Amazon

# Search for books by keyword
amazon = Amazon("your Access Key", "your Secret Access Key")
xml = amazon.itemSearch("Books", Keywords=u"ウェブサービス", ItemPage="1")  # books
print amazon.url  # request URL
#print unicode(xml, 'utf_8')  # Amazon response

# Extract information from the XML
from BeautifulSoup import BeautifulStoneSoup
soup = BeautifulStoneSoup(xml)

items = soup.find("items")
print u"%s件見つかりました" % soup.find("totalresults").contents[0]
total_pages = soup.find("totalpages").contents[0]
cur_page = soup.find("itempage").contents[0]
print u"ページ数: %s/%s" % (cur_page, total_pages)

for item in soup.findAll("item"):
    print item.asin.contents[0], item.author.contents[0], item.title.contents[0]

The output looked like this.

http://webservices.amazon.co.jp/onca/xml?AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&ItemPage=1&Keywords=%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9&Operation=ItemSearch&SearchIndex=Books&Service=AWSECommerceService&Timestamp=2011-03-07T07%3A34%3A13Z&Signature=g5GSp7pBEGEUgundHtiqMHhwhOVjIda/5a1wCGPIkFw%3D

167件見つかりました
ページ数: 1/17

4820742019 岩本 のぞみ 事例でわかるWebサービス・ビジネス―XML、Webサービスのしくみ、基本技術、ビジネスへの適用例が図解でわかる!
4797336838 秋元 裕樹 PHP×WebサービスAPIコネクションズ
4434073435 Sanjiva Weerawarana Webサービスプラットフォームアーキテクチャ
4873110890 イーサン セラミ Webサービスエッセンシャルズ
4891003049 Scott Short XML Webサービス構築ガイド (マイクロソフト公式解説書)
488373174X 成田 雅彦 Webサービス・アプリケーション開発技法―SOAP/WSDL/ebXML
4822281167 嶋本 正 Webサービス完全構築ガイド - XML、SOAP、UDDI、WSDLによる先進Webシステムの設計・実装
4798007064 本 俊也 図解標準 最新Webサービス マスタリングハンドブック―XML、SOAP、WSDL、UDDIの基本から開発まで
4797320680 スティーブ グレアム JavaによるWebサービス構築
4861671000 佐久嶋 ひろみ PHP5 & XMLによるWebサービス構築

That’s all from the Gemba where I tried the Amazon Product Advertising API in Python.

Reference Information