#はじめに
昔は図書館の本すら、自由に読めなかったらしいが、今は自由に読めるし、ブックオフもあるし、更に bookmter もある。恵まれた時代である。僕も bookmeter を愛用させていただいてる。美しいデザイン、知的なユーザー、痒いところに手の届く機能。人類の幸福に多大な貢献をしている bookmeter だが、だからこそ、なぜこれが出来ないのかと思うことがある。例えば、「読みたい本」というブックマークのような機能があって、素晴らしいのだが、検索ができないのである。VIM はヘルプすら検索できるのに。同様に「読んだ本」や「積読」も検索できない。また、タグがないので、バラバラに本がある印象で、どうにもまとまらない。しかし不満ばかり言っても仕方ない。使う側が工夫すれば良いのである。モンスターカスタマーでは、素晴らしい運営者も疲れて辞めてしまうかもしれない。
#したいこと
- 「読みたい本」などの検索
- 本のタグ付け
- ...
まずは、上の2つをやりたい。他にも色々できたら。
#本のデータの取得
まずは本のデータを取る。本のデータの一覧は同じ形式なので同じように取れる。
import requests
from bs4 import BeautifulSoup as bs
import time
import urllib.parse as up
import json
HEADERS={
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"
}
class Selector:
BOOK="li.group__book"
THUMB=".book__thumbnail"
TITLE=".detail__title"
DATE=".detail__date"
AUTHOR=".detail__authors"
PAGE=".detail__page"
def toData(book):
thumb=book.select_one(Selector.THUMB)
if thumb:
img=thumb.find("img")
imgUrl=img.get("src") if img else ""
else:
imgUrl=""
title_e=book.select_one(Selector.TITLE)
title=title_e.text if title_e else ""
href=title_e.find("a").get("href") if title_e else ""
date=book.select_one(Selector.DATE)
date=date.text if date else ""
author=book.select_one(Selector.AUTHOR)
author=author.text if author else ""
page=book.select_one(Selector.PAGE)
page=page.text if page else ""
return {
"imgUrl":imgUrl,
"title":title,
"href":href,
"date":date,
"author":author,
"page":page
}
def __getBooks(soup):
return map(toData,soup.select(Selector.BOOK))
def _getBooks(url,page=1,session=requests):
params={
"page":page
}
res=session.get(url,headers=HEADERS,params=params)
soup=bs(res.text,"html.parser")
return __getBooks(soup)
def getBooks(url,start=1,n=5):
session=requests.Session()
for page in range(start,start+n):
data=list(_getBooks(url,page,session))
if not data:
return
for dat in data:
dat["href"]=up.urljoin(url,dat["href"])
yield dat
time.sleep(1)
同じような関数ばかり並んでるのはご愛敬。肝心なのは getBooks だけだが、一応説明。
###toData
引数 | 意味 |
---|---|
book | 本のデータのスープ |
###toDataの返り値
キー | 値 |
---|---|
imgUrl | 画像のURL |
title | タイトル |
href | 本のURL |
date | 日付(追加日) |
author | 著者名 |
page | 本のページ数 |
###__getBooks
引数 | 意味 |
---|---|
soup | スープ |
返り値は、データのリスト。
###_getBooks
引数 | 意味 |
---|---|
url | URL |
page | サイトのページ数 |
session | セッション |
返り値は、データのリスト。sessionは内部のもの。
###getBooks
引数 | 意味 |
---|---|
url | URL |
start | 最初のページ |
n | データを取るページの数 |
返り値は、データのリスト。
要するに、toData はスープをデータに変換する、__getBooksはスープから本のデータを返す、_getBooks は __getBooks のラッパーのようなもので、getBooks は _getBooks のラッパーのようなもの。
pageというのはページ数で、例えば、ホームの検索窓で、「数学」と入れて調べると、
https://bookmeter.com/search?keyword=%E6%95%B0%E5%AD%A6
に飛ぶ。これに page=3
を足して
https://bookmeter.com/search?keyword=%E6%95%B0%E5%AD%A6&page=3
とすると3ページ目に行く。
##試す
import bookmeter
import time
import json
url="https://bookmeter.com/users/1035737/books/wish"
for data in bookmeter.getBooks(url,start=1,n=10**32):
print(json.dumps(data,ensure_ascii=False,indent=4))
$ python main.py
{
"imgUrl": "https://m.media-amazon.com/images/I/41OCTQEQrbL._SL500_.jpg",
"title": "安部公房とわたし",
"href": "https://bookmeter.com/books/7020962",
"date": "",
"author": "山口 果林",
"page": ""
}
{
"imgUrl": "https://m.media-amazon.com/images/I/510TTCKFQNL._SL500_.jpg",
"title": "イスラーム文化−その根柢にあるもの (岩波文…",
"href": "https://bookmeter.com/books/579483",
"date": "",
"author": "井筒 俊彦",
"page": ""
}
{
"imgUrl": "https://m.media-amazon.com/images/I/51vdg2TkNfL._SL500_.jpg",
"title": "日本史有名人の身体測定",
"href": "https://bookmeter.com/books/10276713",
"date": "",
"author": "篠田 達明",
"page": ""
}
~~ 以下略 ~~
#簡単な検索
データを取れたので、簡単な検索をしてみる。
import time
import json
import docopt
import re
import docopt
__doc__="""
Usage:
search <s> <url>
"""
args=docopt.docopt(__doc__)
s=args["<s>"]
url=args["<url>"]
for data in bookmeter.getBooks(url,start=1,n=10**32):
if re.search(s,data["title"]):
print(json.dumps(data,ensure_ascii=False,indent=4))
$ python main.py 数学 https://bookmeter.com/users/1035737/books/wish
{
"imgUrl": "https://m.media-amazon.com/images/I/51xDl2z9K+L._SL500_.jpg",
"title": "高校数学でわかる流体力学 (ブルーバックス)",
"href": "https://bookmeter.com/books/8095831",
"date": "",
"author": "竹内 淳",
"page": ""
}
{
"imgUrl": "https://m.media-amazon.com/images/I/51G4jU5hGhL._SL500_.jpg",
"title": "高校数学でわかるフーリエ変換―フーリエ級数か…",
"href": "https://bookmeter.com/books/424303",
"date": "",
"author": "竹内 淳",
"page": ""
}
{
"imgUrl": "https://m.media-amazon.com/images/I/416Yus64pNL._SL500_.jpg",
"title": "物語 数学の歴史―正しさへの挑戦 (中公新書)",
"href": "https://bookmeter.com/books/491408",
"date": "",
"author": "加藤 文元",
"page": ""
}
~~ 以下略 ~~
#終わりに
次回はデータベースを作って、もう少し本格的にできるようにしたい。
##コードはこちら