blog.hekt.org

PythonでAmazon Product Advertising APIからデータを取得しようとして挫折した

ので、既成のプラグインにお世話になることに。→AmazonLink

どういうわけか、最初に表示したときにエラーが出ますが、リロードすれば大丈夫。記事を最初に表示するのはだいたい僕なので、特に問題はないはず。

で、Pythonで書いたほう、リクエストURLを生成する部分。PythonでAmazon Product Advertising APIを使う – 人工知能に関する断想録 を参考にさせて頂きました。

#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import urllib, time, base64, hashlib, hmac

class AmazonPAAPI:
    def request(self, query):
        scrtkey = "秘密キー"

        #パラメータをセット
        params = {
            'AWSAccessKeyId'    :"ユーザーID",
            'ItemId'            :query,
            'Operation'         :"ItemLookup",
            'ResponseGroup'     :"ItemAttributes,Images",
            'Service'           :"AWSECommerceService",
            'Timestamp'         :time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
            'Version'           :"2009-10-01",
            'ContentType'       :"text/xml"
            }
        host = "xml-jp.amznxslt.com"
        path = "/onca/xml"

        #キーをリストにしてソート
        keys = params.keys()
        keys.sort()

        #一つの文字列に
        string = ''
        for k in keys:
            string += urllib.quote(k,'') + '=' + urllib.quote(params[k],'') + '&'

        #ベースと合体(最後の&は省く)
        req = "GETn%sn%sn%s" % (host, path, string[:-1])

        #署名を生成
        sig = base64.b64encode(hmac.new(scrtkey,req,hashlib.sha256).digest())
        #urlエンコード
        sig = urllib.quote(sig,'')
        #合体
        url = 'http://%s%s?%sSignature=%s' % (host, path, string, sig)

        return url

Amazon Product Advertising APIでは、ただ必要なパラメータを渡すだけじゃなく、そのパラメータと秘密鍵から計算した署名を付けなければ、結果を返してくれません。その署名を計算するためにこういう処理が必要になります。URLエンコードする際に、urllib.quote(s)ではなく、urllib.quote(s,'')としたのは、urllib.quote()がエンコードしない文字として”/”(スラッシュ)を初期値で持っているからです。これをそのままにしておくと、”ContentType=text/xml”とか、”Style=http://www~”とかでxsltのアドレスを指定したときに、スラッシュがエンコードされないので、署名が承認されません。

これにXMLから情報を取得する部分を書き足して、PHPでinclude(amazon.py?q=479733665X)とかやって記事に埋め込もうと思っていたのですが、タイトルの通り挫折。ローカルのPython2.6ではちゃんと動いたのですが、XREAのサーバーにインストールされているPython(2.4.2)が古くて動きませんでした。せめて2.5.xにして欲しい……。