LoginSignup
1
3

More than 1 year has passed since last update.

BookoffオンラインのAPIをつくってみた。 #3 (改良)

Last updated at Posted at 2021-10-25

はじめに

前回はこちら

本当はデータベースを作りたかったが、一度に最大5000件しか取れないという壁にぶつかり、どうも深刻な感じなのでとりあえず諦めた。
前回と前々回で、いくつか関数を作ったが、もう少し改良。

データの取得

一回目の searchN を改良。

util.py
from . import api
import re
import time

def search(query,title="",author="",priceFrom=0,priceUntil=10**32,onlyStocked=True,n=5,type_=api.SearchType.BOOK,timeout=30):
        i=0
        startTime=time.time()
        for data in api.searchN(query,n=10**32,type_=type_):
                if i >= n:
                        break
                if time.time() - startTime > timeout:
                        break
                if (not title or re.search(title,data["title"])) and \
                        (not author or re.search(author,data["author"])) and \
                        priceFrom <= data["price"] < priceUntil and \
                        (not onlyStocked or data["stocked"]):
                        yield data
                        i+=1

引数 意味
query 検索する文字
title タイトル (部分一致)
author 著者名 (部分一致)
priceFrom {priceFrom} 円以上
priceUntil {priceUntil} 円未満
onlyStocked 在庫の在るもののみを返す
n データの個数 (最大)
type データのタイプ
timeout タイムアウト

query と title があるのは野暮なようだが、例えば著者名で検索したいとき、 query = title なら無理やし、 query=title+" "+author ではauthorに正規表現を使いたいときにヒットしない。まあ改良してもこんなもの。(笑)
一応タイムアウトを付けた。

試す

main.py
from bookoff import api
import getpass
import requests
from bookoff import util
import sys
import json

author=sys.argv[1]
for data in util.search(author,author=author,priceUntil=220):
        print(json.dumps(data,indent=4,ensure_ascii=False))
実行結果
$ python main.py 安部公房
{
    "title": "砂の女(新潮文庫)",
    "url": "https://www.bookoffonline.co.jp/old/0015580570",
    "author": "安部公房",
    "price": 200,
    "stocked": true
}
{
    "title": "壁(新潮文庫)",
    "url": "https://www.bookoffonline.co.jp/old/0015580566",
    "author": "安部公房",
    "price": 200,
    "stocked": true
}
{
    "title": "笑う月(新潮文庫)",
    "url": "https://www.bookoffonline.co.jp/old/0015580572",
    "author": "安部公房",
    "price": 200,
    "stocked": true
}
{
    "title": "箱男(新潮文庫)",
    "url": "https://www.bookoffonline.co.jp/old/0015580571",
    "author": "安部公房",
    "price": 200,
    "stocked": true
}
{
    "title": "こころの声を聴く 河合隼雄対話集(新潮文庫)",
    "url": "https://www.bookoffonline.co.jp/old/0012419276",
    "author": "河合隼雄,安部公房,山田太一,谷川俊太郎,白洲正子",
    "price": 200,
    "stocked": true
}

なかなか有能である。前回のものと組み合わせて、好きな著者の安い本を選んでカートに入れてみる。

好きな著者の安い本をカートに入れる

main.py
import docopt
import getpass

PRICE_UNTIL=220

__doc__="""
Usage:
        addcheaps <author> [(-n <number>)]  [(-m <mail>)]
"""

def main(argv=sys.argv[1:]):
        args=docopt.docopt(__doc__)

        author=args["<author>"]
        number=int(args["<number>"]) if args["-n"] else 5
        mail=args["<mail>"] or input("mail : ")
        pw=getpass.getpass()

        author=sys.argv[1]
        client=api.Client(mail,pw)
        if not client.logined:
                print("Failed to login")
                return
        for data in util.search(author,author=author,priceUntil=PRICE_UNTIL):
                print(data["title"],data["price"])
                client.addCart(util.getidInUrl(data["url"]))

if __name__ == "__main__":
        main()
実行結果
$ python main.py 梅棹忠夫 -m tetsuya1729@icloud.com                        
Password:              
知的生産の技術(岩波新書) 200                                         
日本文明77の鍵(文春新書) 200                            
二十一世紀の人類像 民族問題をかんがえる(講談社学術文庫) 200  

タイトルから ID を取るのは遅いので、util.Client ではなく api.Client を使った。(改悪か?)
ここまでくれば、中々実用的である。

終わりに

本を買うために、プログラミングをするなんて知的すぎんか 。。。只の陰キャラの末路と言う気もせんではないが。やはりスポーツをやらねば。(笑)

コード

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3