wiki:PyAmazon

PyAmazon

 http://www.josephson.org/projects/pyamazon/

v0.65 についてのメモ.仕様が割とひどい.

基本

以下は amazon.co.jp から「のだめ」を検索した結果を適当に出力する例.

import amazon

LOCALE = 'jp'
ACCESS_KEY = 'your access key'

amazon.setLocale(LOCALE)
amazon.setLicense(ACCESS_KEY)

data = amazon.searchByBlended(unicode('のだめ', 'euc-jp').encode('utf-8'))

for p in data.ProductLine:
    details = p.ProductInfo.Details
    #
    for d in details:
        for key, val in d.__dict__.iteritems():
            print '%(key)s: %(val)s' % locals()

searchByKeyword の罠

searchByKeyword 関数で,あるカテゴリの中から検索することができる.

  • しかし,searchByBlended と違って data をそのまま返さずに data.Details を返しやがる (amazon.py の 312 行目を参照) ので,searchByKeyword を使うと,TotalPagesTotalResults を得ることができない
  • さらに,searchByKeyword の引数に,デフォルトで product_line="books" というのが入っているが,ロケールを jp にした場合はこれだと正しく検索できない.jp ロケールで有効な product_line は以下の通り (たぶん).
モード内容モード内容
books-jp和書books-us洋書
music-jpポピュラー音楽classical-jpクラシック音楽
dvd-jpDVDvhs-jpビデオ
electronics-jpエレクトロニクスkitchen-jpホーム&キッチン
software-jpソフトウェアvideogames-jpゲーム
magazines-jp雑誌toys-jpおもちゃ&ホビー
photo-jppc-hardware-jp

searchByBlended の罠

searchByBlended 関数は Amazon に対して全体検索をかけることが可能.

searchByKeyword のように,この関数にも引数に page というのがあるが,ページ指定はできない.何のための引数なのか,かなり謎.

もっとも,searchByBlended の場合にページ指定ができないのは Amazon API 側の仕様のようだが.

データの整合性

属性の有無

PyAmazon は内部で Amazon API の XML を呼び出して xml.dom.minidom で解析した後,unmarshal という関数で階層構造に沿ってオブジェクトを作っている.そのため,XML の構造がそのまま Python のオブジェクトに継承されている.

そのせいか,結果によってあったりなかったりする属性があるので,適切なエラー処理を書く必要がある.

data = amazon.searchByBlended(unicode('のだめ', 'euc-jp').encode('utf-8'))
d = data.ProductLine[0].ProductInfo.Details[0]

d.ProductDescription                    # AttributeError を引き起こす可能性が高い
getattr(d, 'ProductDescription', None)  # こちらの方が安全

ちなみに,pydoc に書いてある,属性として含む可能性のあるものは以下の通り.

属性名内容属性名内容属性名内容
AsinAmazon の IDAuthors著者リストAvailability「○日以内に発送」など
BrowseList関連のあるカテゴリのリストCatalogカタログのタイプ (Book など)CollectiblePrice価格?
ImageUrlLarge画像 URLImageUrlMedium画像 URLImageUrlSmall画像 URL
IsbnISBN 番号ListPrice価格?Lists
Manufacturer出版社Mediaメディア(「音楽CD」など)NumMediaメディアの数(CD何枚,など)
OurPriceAmazon での価格ProductNameアイテムの名前ReleaseDateリリース日
ReviewsレビューSalesRank順位SimilarProducts関連のあるアイテムのリスト
ThirdPartyNewPrice価格?URLAmazon の URL

が,以上にリストされていない属性も多々あるので以下に少し補足しておく.

属性名内容属性名内容
ProductDescription商品の説明Artistsアーティスト名 (Authors とは別)
TracksCD等の場合のトラック名リストPlatforms動作環境

型の整合性

たとえば Artists.Artist の中身が list になったり str になったりする.ちゃんと処理してやらないとハマる.

ATTRS = ['Authors', 'Artists', 'Tracks']

data = amazon.searchByKeyword(unicode('のだめ', 'euc-jp').encode('utf-8'), product_line='classical-jp')

for attr in ATTRS:
    print '%s: ' % attr
    for d in data:
        authors = getattr(d, attr, None)
        #
        if isinstance(authors, amazon.Bag):
            authors = getattr(authors, attr[:-1], None)
            #
            if isinstance(authors, list): # リストの場合
                for a in authors:
                    print '  ', a
            #
            elif authors is not None: # リストでも None でもない場合は str と仮定
                print '  ', authors