Main Contents

2006年10月01日

kakaku.com Web API for Python (ElementTree使用版)

このエントリーをはてなブックマークする このエントリーを含むはてなブックマーク | Save This Page (del.icio.us)

ついさっきkh.log - kakaku.com Web API for Pythonを書いたところ ですが、ElementTreeという便利なモジュール(python 2.5から標準モジュールになった )を知ったので、書き換えてみました。一応、前のものも残しています。

ElementTreeの使いかたは、perezvonの日記 - Raku APIElementTree Overview ::: www.effbot.orgを参考にさせていただきました。

KakakuComAPIクラス(ElementTree版)をダウンロードする

以下のようなかんじ。だいぶすっきりした。

import urllib, types

try:
    import xml.etree.ElementTree as ET
except ImportError:
    try:
        import cElementTree as ET
    except:
        import elementtree.ElementTree as ET

from xml.dom import minidom

class KakakuComAPI(object):
    API_ENDPOINT = r'http://api.kakaku.com/Ver1/ItemSearch.asp'
    UNMARSHALLERS = {
        'Item': lambda e: dict([(c.tag, c.text) for c in e]),
        'ProductInfo': lambda e: [c.text for c in e if c.tag == 'Item'],
        'Error': lambda e: e[0].text,
        }

    @classmethod
    def search(cls, **args):
        params = cls.__parameterize(args)
        url = cls.API_ENDPOINT + '?' + params
        result = {}
        f = urllib.urlopen(url)
        for event, elem in ET.iterparse(f):
            unmarshal = cls.UNMARSHALLERS.get(elem.tag, lambda e: e.text)
            elem.text = unmarshal(elem)
            if elem.tag in ('ProductInfo', 'Error', 'NumOfResult'):
                result[elem.tag] = elem.text

        f.close()
        result['RequestedUrl'] = url
        return result

    @classmethod
    def __parameterize(cls, args):

        kw = args.get('Keyword')
        arg_enc = args.get('ArgsEncode')
        if type(kw) is types.UnicodeType:
            kw = kw.encode('shift_jis', 'ignore')
        elif arg_enc:
            kw = kw.decode(arg_enc, 'ignore').encode('shift_jis', 'ignore')

        params = []
        params.append("%s=%s" % ('Keyword', urllib.quote(kw)))

        for p in ('ResultSet', 'CategoryGroup', 'SortOrder', 'PageNum'):
            v = args.get(p)
            if v != None:
                params.append("%s=%s" % (p, urllib.quote(v)))

        return '&'.join(params)

以下、使用例。ここは前と同じ。

Keywordに日本語を含む場合はsjisで渡すか、unicodeで渡すか、そうでなければArgsEncodeで明示するかする必要があることに注意。

from kakaku_api import KakakuComAPI

r = KakakuComAPI.search(Keyword="vaio")
r = KakakuComAPI.search(Keyword=u"バイオ")
r = KakakuComAPI.search(Keyword=u"バイオ".encode("shift_jis"))
r = KakakuComAPI.search(Keyword=u"バイオ".encode("euc-jp"), ArgsEncode="euc-jp")
r = KakakuComAPI.search(Keyword="vaio",
                        ResultSet="medium",
                        SortOrder="pricerank",
                        PageNum="4",
                        CategoryGroup="Pc")

結果の形式が前回とはちょっと違っているので注意。商品情報はItemsというキーで格納していたのですが、今回はProductInfoキーで格納してます。


{'ProductInfo': [{'BbsPageUrl': u'http://kakaku.com/bbs/Main.asp?PrdKey=01307211611',
    'CategoryName': u'\u30d1\u30bd\u30b3\u30f3\u5468\u8fba\u6a5f\u5668>MP3',
    'ImageUrl': u'http://img.kakaku.com/images/productimage/m/01307211611.jpg',
    'ItemPageUrl': u'http://kakaku.com/item/01307211611/',
    'LowestPrice': u'15298',
    'MakerName': u'SONY',
    'NumOfBbs': u'516',
    'ProductID': u'01307211611',
    'ProductName': u'NW-E005 \u30d0\u30a4\u30aa\u30ec\u30c3\u30c8 (2GB)',
    'PvRanking': u'4',
    'ReviewPageUrl': u'http://kakaku.com/prdevaluate/evaluate.asp?PrdKey=01307211611'},
  ... ],
 'NumOfResult': u'762',
 'RequestedUrl': 'http://api.kakaku.com/Ver1/ItemSearch.asp?Keyword=vaio&ResultSet=medium&CategoryGroup=Pc&SortOrder=pricerank&PageNum=4'}

または、エラーがあった場合は、

{'Error': u'\nItemNotFound',
 'RequestedUrl': 'http://api.kakaku.com/Ver1/ItemSearch.asp?Keyword=vaio0000'}

TrackBacks

トラックバックURL:

Comments

Post a comment

コメントフォーム