はじめに
前回はデータを取得したので、次はユーザー名から「読みたい本」や「読んだ本」を取れるようにしたい。
名前からユーザーIDの取得
「読みたい本」や「読んだ本」の URL は、
読みたい本:https://bookmeter.com/users/<userid>/books/wish
読んだ本 : https://bookmeter.com/users/<userid>/books/read
のようになっている。(<userid>=ユーザーID)
ユーザーIDはユーザー名とは別のものなので、まずはユーザー名からユーザーIDを取得する。
流れ
- 名前で検索してユーザーの一覧を取得。
- そこから名前が完全一致のデータを取得。(同名別人の可能性はあるが、名前の付け方が悪いせいにしておく。笑)
- IDを取得。
ユーザーの検索
ユーザーを検索するには
https://bookmeter.com/users/search
を使えば良い。ブラウザからは、普通のページが返ってくるが、User-Agent だけ付けたリクエストをすると JSON 形式のデータが返ってくる。以下コード。前回の続き。
コード
def searchUsers(name):
params={
"name":name
}
res=requests.get(SEARCH_USERS_URL,headers=HEADERS,params=params)
#soup=bs(res.text,"html.parser")
data=json.loads(res.text)
return data["resources"]
試す
import bookmeter
import json
import sys
name=sys.argv[1]
for data in bookmeter.searchUsers(name):
print(json.dumps(data,indent=4,ensure_ascii=False))
$ python main.py 田中
{
"id": 756064,
"path": "/users/756064",
"name": "田中田中",
"image": "https://img.bookmeter.com/profile_image/normals/757/1490774229046470.jpg",
"sign_up_date": "2017年"
}
{
"id": 747469,
"path": "/users/747469",
"name": "田中田中",
"image": "https://img.bookmeter.com/profile_image/normals/748/1487672432957391.png",
"sign_up_date": "2017年"
}
{
"id": 817445,
"path": "/users/817445",
"name": "田中田中",
"image": "https://bookmeter.com/images/common/profile_image.png",
"sign_up_date": "2017年"
~~以下略~~
}
完全一致のデータを取得
さっきのデータから、名前が完全一致したものを返すだけ。
import re
def getUser(name):
for user in searchUsers(name):
if re.fullmatch(name,user["name"]):
return user
return None
import bookmeter
import sys
import json
name=sys.argv[1]
data=bookmeter.getUser(name)
if data:
print(json.dumps(data,indent=4,ensure_ascii=False))
$ python main.py 田中田中
{
"id": 756064,
"path": "/users/756064",
"name": "田中田中",
"image": "https://img.bookmeter.com/profile_image/normals/757/1490774229046470.jpg",
"sign_up_date": "2017年"
}
$ python main.py 田中田中田中
$ python main.py vectorcc
{
"id": 1035737,
"path": "/users/1035737",
"name": "vectorcc",
"image": "https://bookmeter.com/images/common/profile_image.png",
"sign_up_date": "2019年"
}
IDの取得は data["id"]
とすれば良い。
まとめる
以上のコードをまとめる。
class _User:
URL=URL+"/users/{0}"
class Type:
WANT="wish"
READ="read"
READING="reading"
def __init__(self,name):
self.name=name
self.id=self.getid(name)
if not self.id:
raise Exception("Don't find id of {0}.".format(self.name))
@property
def wanturl(self):
return self.url+"/books/wish"
@property
def readurl(self):
return self.url+"/books/read"
@property
def url(self):
return self.URL.format(self.id)
@staticmethod
def getid(name):
user=getUser(name)
return user["id"] if user else None
あるユーザーの読んだ本のデータを取得
前回のものと、上の関数を組み合わせて、あるユーザーの読んだ本のデータを取ってみる。
import bookmeter
import json
import sys
name=sys.argv[1]
user=bookmeter._User(name)
for data in bookmeter.getBooks(user.readurl,n=1000):
print(json.dumps(data,indent=4,ensure_ascii=False))
$ python main.py 田中
{
"imgUrl": "https://m.media-amazon.com/images/I/61fkTy7nTFL._SL500_.jpg",
"title": "ソードアート・オンライン (6) ファントム…",
"href": "https://bookmeter.com/books/1651321",
"date": "2013/01/09",
"author": "川原 礫",
"page": "445"
}
{
"imgUrl": "https://m.media-amazon.com/images/I/51ilIORClBL._SL500_.jpg",
"title": "ソードアート・オンライン〈5〉ファントム・バ…",
"href": "https://bookmeter.com/books/625788",
"date": "2013/01/09",
"author": "川原 礫",
"page": "297"
}
{
"imgUrl": "https://m.media-amazon.com/images/I/613gLJ4BcEL._SL500_.jpg",
"title": "バッカーノ! 1935-B Dr. Feel…",
"href": "https://bookmeter.com/books/5699809",
"date": "2012/12/30",
"author": "成田良悟",
"page": "328"
}
~~以下略~~
以上!
おわりに
次回こそはデータベースを作りたい。一々調べれば良いようだが、手元にあった方が都合が良いこともあると思う。