GAEでPythonとDjangoでAmazonAPI使ったWEBアプリを作成中。
AmazonAPIはPyzonを使っていて、返ってきたxmlはBeautifulSoupを使って読んでいる。
が、BeautifulSoupがよく分からず、どんなコードならいいのか全然わからない。
あれはうまくいったのに、これはうまくいかないなんて全然分からなかったので、あれとこれをメモっておく。
うまくいったコード
from pyzon import Pyzon from BeautifulSoup import BeautifulStoneSoup import re access_key_id = **** secret_access_key = **** associate_tag = **** #本を検索する def book_search(bookname): pyzon = Pyzon(access_key_id, secret_access_key, associate_tag) xml = pyzon.ItemSearch(search_index='Books', Keywords=bookname,ResponseGroup='Small,Images') soup = BeautifulStoneSoup(xml) #asin,smallimage,title,author,manufacturerのリスト作る bookinfo_list = [[item.asin.contents[0],item.smallimage,item.title.contents[0],item.author,item.manufacturer.contents[0]] for item in soup.findAll('item')] #smallimage,authorはNONEの可能性あり、チェックしてNONEの対応して、余計なものを省く idx = 0 for bookinfo in bookinfo_list: if not bookinfo[1] == 'NONE': p = re.compile('^(?P.+?)') m = p.match(str(bookinfo[1])) if m: bookinfo_list[idx][1] = m.group('url') if not bookinfo[3] == 'NONE': p = re.compile('^(?P.+?)') m = p.match(str(bookinfo[3])) if m: bookinfo_list[idx][3] = m.group('author') idx += 1 return bookinfo_list
うまくいかなかったコード
from pyzon import Pyzon from BeautifulSoup import BeautifulStoneSoup access_key_id = **** secret_access_key = **** associate_tag = **** #1冊の本の情報を取り出す(IdTypeはASIN)※amazonAPIのitemLookup def book_lookup(asin): pyzon = Pyzon(access_key_id, secret_access_key, associate_tag) xml = pyzon.ItemLookup(item_id=str(asin),ResponseGroup='Small,Images') soup = BeautifulStoneSoup(xml) #asin,smallimage,mediumimage,largeimage,title,author,manufacturerのリスト作る asin = soup.asin.contents[0] title = soup.title.contents[0] manufacturer = soup.manufacturer.contents[0] #imageとauthorはNONEの可能性があるので、チェックした後、値を格納。 smallimage_url = '' mediumimage_url = '' largeimage_url = '' author = '' if not soup.smallimage == 'NONE': smallimage_url = soup.smallimage.url.contents[0] if not soup.mediumimage == 'NONE': mediumimage_url = soup.mediumimage.url.contents[0] if not soup.largeimage == 'NONE': largeimage_url = soup.largeimage.url.contents[0] if not soup.author == 'NONE': author = soup.author.contents[0] return [int(asin),str(smallimage_url),str(mediumimage_url),str(largeimage_url),title,author,manufacturer]
うまくいかなかった方は、soup.smallimageとか、soup.authorとかの値が無いときに、最後の数行のif分のところで、無い値の部分がエラーになる。
AmazonAPIがJSONで返してくれたらどんだけ楽なことか。PythonでXMLをJSONに直すのも簡単ではなさそうなので、XMLをBeautifulSoup読む方法で粘ろう。
ちなみに、うまくいかなかったコードの修正版がこれ。
from pyzon import Pyzon from BeautifulSoup import BeautifulStoneSoup import re access_key_id = **** secret_access_key = **** associate_tag = **** #1冊の本の情報を取り出す(IdTypeはASIN)※amazonAPIのitemLookup def book_lookup(asin): pyzon = Pyzon(access_key_id, secret_access_key, associate_tag) xml = pyzon.ItemLookup(item_id=str(asin),ResponseGroup='Small,Images') soup = BeautifulStoneSoup(xml) #asin,smallimage,mediumimage,largeimage,title,author,manufacturerのリスト作る bookinfo_list = [[item.asin.contents[0],item.smallimage,item.mediumimage,item.largeimage,item.title.contents[0],item.author,item.manufacturer.contents[0]] for item in soup.findAll('item')] #imageとauthorはNONEの可能性があるので、チェックした後、値を格納。 idx = 0 for bookinfo in bookinfo_list: if not bookinfo[1] == 'NONE': p = re.compile('^(?P.+?)') m = p.match(str(bookinfo[1])) if m: bookinfo_list[idx][1] = m.group('url') if not bookinfo[2] == 'NONE': p = re.compile('^(?P.+?)') m = p.match(str(bookinfo[2])) if m: bookinfo_list[idx][2] = m.group('url') if not bookinfo[3] == 'NONE': p = re.compile('^(?P.+?)') m = p.match(str(bookinfo[3])) if m: bookinfo_list[idx][3] = m.group('url') if not bookinfo[5] == 'NONE': p = re.compile('^(?P.+?)') m = p.match(str(bookinfo[5])) if m: bookinfo_list[idx][5] = unicode(m.group('author'),'utf-8') idx += 1 return bookinfo_list[0]