AmazonのProduct Advertising APIを使ってISBNから書籍情報を取得する

の続きで、バーコードから読み取ったISBNをAmazonから提供されているAmazonログインに入力して書籍情報を取得する。

Product Advertising APIの使用方法

Representational State Transfer - Wikipediaを用いたWebAPIで、

  1. 認証情報や欲しい情報を取得するための引数をつなげたURLを送信
  2. 帰ってきたxmlから情報を取得

という流れになる。
URLの生成やリクエストの送信を隠蔽したモジュールを公開してくださっている方がいたので、ありがたく使わせていただく。
PythonでAmazon Product Advertising APIを使う - 人工知能に関する断創録

PythonWebカメラからバーコードを読み、取得したISBNからProduct Advertising APIを使って書籍情報の取得

ソースコードのタイトルがだんだん長くなってきましたが、今回も分割せず一本道のソースコードになっております。そろそろリファクタリングした方がいいかな...

import cv
import time
import zbar
import Image
from amazon import Amazon
from BeautifulSoup import BeautifulStoneSoup

cv.namedWindow("camera", 1)
capture = cv.CreateCameraCapture(0)

width = None
height = None

if width is None:
    width = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_WIDTH))
else:
    cv.SetCaptureProperty(capture,cv.CV_CAP_PROP_FRAME_WIDTH,width)    

if height is None:
    height = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_HEIGHT))
else:
    cv.SetCaptureProperty(capture,cv.CV_CAP_PROP_FRAME_HEIGHT,height) 

amazon = Amazon("your_access_key","your_secret_access_key")

while True:
    img = cv.QueryFrame(capture)
    size = cv.GetSize(img)
    gray_img = cv.CreateImage(size, cv.IPL_DEPTH_8U, 1)
    cv.CvtColor(img, gray_img, cv.CV_BGR2GRAY)
    
    scanner = zbar.ImageScanner()
    scanner.parse_config('enable')

    zbar_img = zbar.Image(gray_img.width, gray_img.height, 'Y800', gray_img.tostring())
    scanner.scan(zbar_img)

    for symbol in zbar_img:
        print 'decoded', symbol.type, 'symbol', '"%s"' % symbol.data
        if symbol.type == 'ISBN10':
            xml = amazon.itemLookup(symbol.data, SearchIndex="Books", IdType="ISBN",
                    ResponseGroup="Large,Similarities", ReviewPage="1")
            print amazon.url
            
            soup = BeautifulStoneSoup(xml)
            item = soup.find("item")

            print item.asin
            print item.itemattributes.title
            print item.itemattributes.listprice.amount

    cv.ShowImage("camera", gray_img)
    k = cv.WaitKey(10);
    if k == 'f':
        break

前回から追加した部分は、

  • Amazonインスタンスを生成してitemLookupメソッドにISBNを渡す
  • 帰ってきたxmlをBeautifulSoupでパースして情報を取得・表示

現時点での問題点としては、

  1. 同じ書籍でもISBNが取得されれば10msごとにProduct Advertising APIを叩いてしまう
    • 保存用のdictionary型を生成して同じ書籍は検索しないようにする
    • dictionary型をpickleする方法とsqliteを使う方法があるけどどちらの方がいいのかな?要素数が変動する場合もあるのでdictionary型の方が楽そうだけど...
  2. 柄のある背景にバーコードが印刷されている場合に認識率が悪い
    • グレースケールではなく背景の柄を消すような二値化処理が出来れば認識率は上がるはず
  3. ソースコードが醜い

上記の問題点を修正しつつ、次回は、mechanizeと絡めていきたい。