bookmeterのAPIをつくってみた。 #2 (簡単なユーザーデータの取得)

#はじめに
 [前回](https://qiita.com/tetsuya111/items/eac5346e7c2d1b06b1d3)はデータを取得したので、次はユーザー名から「読みたい本」や「読んだ本」を取れるようにしたい。

#名前からユーザー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](https://bookmeter.com/users/search)
を使えば良い。ブラウザからは、普通のページが返ってくるが、User-Agent だけ付けたリクエストをすると JSON 形式のデータが返ってくる。以下コード。前回の続き。

###コード
```python:bookmeter.py
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"]
```

###試す

```python:main.py
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))
```

```shell:実行結果
$ 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年"

～～以下略～～
}
```

#完全一致のデータを取得

さっきのデータから、名前が完全一致したものを返すだけ。

```python:bookmeter.py
import re
def getUser(name):
        for user in searchUsers(name):
                if re.fullmatch(name,user["name"]):
                        return user
        return None
```

```python:main.py
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))
```

```shell:実行結果
$ 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"]` とすれば良い。

#まとめる

以上のコードをまとめる。

```python:bookmeter.py
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
```

#あるユーザーの読んだ本のデータを取得

[前回](https://qiita.com/tetsuya111/items/eac5346e7c2d1b06b1d3)のものと、上の関数を組み合わせて、あるユーザーの読んだ本のデータを取ってみる。

```python:main.py
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))
```

```shell:実行結果
$ 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"
}

～～以下略～～
```

以上！

#おわりに
 次回こそはデータベースを作りたい。一々調べれば良いようだが、手元にあった方が都合が良いこともあると思う。

##[コードはこちら](https://github.com/tetsuya111/util/blob/main/bookmeter.py)