📌

bookersの投稿API(python)を使ってみた

に公開

bookersについて

有料予想・有料記事を登録できるサイト
記事投稿できるAPIが提供されている為、競馬予想から競馬予想投稿までを自動化してみました。

投稿API用シークレットキー

bookersにログイン後、アカウント設定の最下部の投稿API用シークレットキーを取得する。
投稿API用シークレットキー

記事一覧取得[GET]

エンドポイント
/api/postcreate/

pythonサンプルコード

import requests
# Tokenに投稿API用シークレットキーを指定する
headers = {
    'Authorization': 'Token *****************',
}
res = requests.get('https://bookers.tech/api/postcreate/', headers=headers)
print(res.json())

最新20件の記事詳細と次の20件取得用のURLが返却される。

レスポンス

  • 成功:200
  • 失敗:403

JSON構造体

{
    "count": 2,
    "next": None,
    "previous": None,
    "results": [
        {
            "uuid": "99999999-9999-9999-9999-999999999999",
            "title": "2023/2/6(月)厳選5鞍",
            "category": 2,
            "description": "有料記事の無料部分",
            "text": "有料記事の有料部分。",
            "price": 100,
            "limited_number": 0,
            "is_shared": false,
            "signature": "99999999-9999-9999-9999-999999999999"
        },
        {
            "uuid": "99999999-9999-9999-9999-999999999999",
            "title": "テスト2",
            "category": 2,
            "description": "有料記事の無料部分。",
            "text": "有料記事の有料部分。",
            "price": 100,
            "limited_number": 0,
            "is_shared": false,
            "signature": "99999999-9999-9999-9999-999999999999"
        }
    ]
}

リソースで使用されているプロパティ

項目名 説明
uuid str uuid
title str(UTF-8) タイトル(255文字まで)
category int カテゴリ
(1:その他,2:競馬,3:競艇,4:競輪,5:テクノロジー,6:ビジネス,7:漫画,8:創作,9:音楽,10:ライフスタイル,11:コラム)
description str(UTF-8) 有料記事の無料部分。markdown記法対応
text str(UTF-8) 有料記事の有料部分。markdown記法対応
price int<0~50000> 価格
2023.02.05現在は、10000まで設定可能
limited_number int<1~> 有料販売記事数
is_shared bool 無料プレゼントURLの有効化フラグ
signature str 署名

記事詳細取得[GET]

uuidを指定することで、単一記事の詳細情報を取得できる。

エンドポイント
/api/postupdate/

pythonサンプルコード

import requests
# Tokenに投稿API用シークレットキーを指定する
headers = {
    'Authorization': 'Token *****************',
}
# uuid 99999999-9999-9999-9999-999999999999 とした場合
requests.get('https://bookers.tech/api/postupdate/99999999-9999-9999-9999-999999999999/',
    headers=headers)

レスポンス

  • 成功:200
  • 失敗:403

記事投稿[POST]

記事投稿に成功した場合は、採番されたuuidが返却される。

エンドポイント
/api/postcreate/

pythonサンプルコード

import requests
import json
# Tokenに投稿API用シークレットキーを指定する
headers = {
    'Authorization': 'Token ******************',
    'Content-Type': 'application/json',
}
data = {
    "title": "テスト2",
    "category": 2,
    "description": "有料記事の無料部分",
    "text": "有料記事の有料部分",
    "price": 100,
    "is_shared": False,
}
res = requests.post('https://bookers.tech/api/postcreate/',
    headers=headers,
    data=json.dumps(data))

レスポンス

  • 成功:201
  • 失敗:400

記事更新[PATCH]

uuidを指定し、記事の詳細情報を更新できる。

エンドポイント
/api/postupdate/

pythonサンプルコード(※タイトルを更新するサンプル)

import requests
import json
# Tokenに投稿API用シークレットキーを指定する
headers = {
    'Authorization': 'Token ******************',
    'Content-Type': 'application/json',
}
data = {
    'title' :'元小池の競馬AI予想!2023/2/5(日)厳選5鞍(Twitterのいいねで無料)',
}
# uuid 99999999-9999-9999-9999-999999999999 とした場合
res = requests.patch('https://bookers.tech/api/postupdate/99999999-9999-9999-9999-999999999999/',
    headers=headers,
    data=json.dumps(data))

レスポンス

  • 成功:200
  • 失敗:403

自作メソッド

記事一覧取得では、最大20件取得できる仕様のため、全件表示できる自作メソッドと記事投稿のメソッドを作成。

import json
import requests
import time

def get_article_list() -> None:
    """
    記事一覧を表示する。
    """
    print('get article list start')

    # Tokenに投稿API用シークレットキーを指定する
    headers = {
        'Authorization': 'Token *****************',
    }
    # APIリクエストURL
    url = 'https://bookers.tech/api/postcreate/'

    # カウント
    count = 1

    while True:
        # 1秒スリープ
        time.sleep(1)
        # APIリクエスト(最新20件の記事詳細と次の20件取得用のURLが返却される)
        res = requests.get(url, headers=headers)

        # 無事レスポンスが返ってきたら中身を出力
        if res.status_code == 200:
            # JSONデータに変換
            json_data = res.json()

            # キーを表示
            print(json_data.keys())

            print(json_data['count'])
            print(json_data['next'])
            print(json_data['previous'])

            # リクエストURLを更新
            url = json_data['next']

            # JSONデータを表示
            for json_obj  in json_data['results']:
                print(str(count) + '件目')
                # JSONの表示
                __display_json(json_obj)
                count += 1

            # リクエストURLがNoneの場合は、ループ終了
            if url == None:
                break
        else:
            print('取得失敗' + res.text)
            break

    print('get article list end')

def __display_json(json_obj: dict) -> None:
    """
    JSONを表示する

    Parameters
    ----------
    json_obj : dict
        JSONオブジェクト
    """
    # 各項目を表示
    print('=================================================================')
    print('uuid:' + json_obj['uuid'])
    print('タイトル(title):' + json_obj['title'])
    print('カテゴリ(category):' + str(json_obj['category']))
    print('無料記事部分(description):' + json_obj['description'])
    print('有料記事部分(text):' + json_obj['text'])
    print('価格(price):' + str(json_obj['price']))
    print('有料販売記事数(limited_number):' + str(json_obj['limited_number']))
    print('無料プレゼントURLの有効化フラグ(is_shared):' + str(json_obj['is_shared']))
    print('著名(signature):' + json_obj['signature'])
    print('=================================================================')

def create_article(title: str,
        free_text: str,
        paid_text: str,
        category=2,
        price=100,
        is_shared=False) -> None:
    """
    記事を投稿する。

    Parameters
    ----------
    title : str
        記事のタイトル
    free_text : str
        有料記事の無料記事部分の内容
    paid_text : str
        有料記事の有料記事部分の内容
    category : int
        記事のカテゴリ(デフォルトは2)
        1:その他,2:競馬,3:競艇,4:競輪,5:テクノロジー,
        6:ビジネス,7:漫画,8:創作,9:音楽,10:ライフスタイル,
        11:コラム
    price : int
        記事の価格(デフォルトは100円)
    is_shared : bool
        無料プレゼントURLの有効化フラグ。(デフォルトはFalse)
    """
    print('create article start')

    # Tokenに投稿API用シークレットキーを指定する
    headers = {
        'Authorization': 'Token *****************',
        'Content-Type': 'application/json',
    }
    data = {
        'title': title,
        'category': category,
        'description': free_text,
        'text': paid_text,
        'price': price,
        'is_shared': is_shared,
    }
    res = requests.post('https://bookers.tech/api/postcreate/',
        headers=headers,
        data=json.dumps(data))

    # 無事レスポンスが返ってきたら中身を出力
    if res.status_code == 201:
        print('記事作成成功')
        # JSONデータに変換
        json_obj = res.json()
        # キーを表示
        print(json_obj.keys())
        # JSONの表示
        __display_json(json_obj)
    else:
        print('記事作成失敗' + res.text)

    print('create article end')

エンドポイントのまとめ

エンドポイント 説明
/api/postcreate/ 記事一覧取得[GET]、記事作成[POST]
/api/postupdate/ 記事詳細取得[GET]、記事更新[PATCH]
/api/postdlcupdate/ DLC(ダウンロードコンテンツ)追加[PATCH]
/api/magazinepostcreate/ マガジン/記事の紐づけ[POST]
/api/magazinepostdelete/ マガジン/記事の紐づけ解除[POST]
/api/postcampaignupdate/ Twitter拡散キャンペーン追加[PATCH]
/api/postdraftcreate/ 下書き保存[POST]
挙動は、既存の記事作成[POST]APIと同様
また、下書き記事を記事更新APIで更新すると記事が公開される仕様

今回は、/api/postcreate//api/postupdate/について利用してみたが、他にも機能についても今後、検証したいと思います。

APIを使用してみての感想

1. 非公開(下書き)の状態で、POSTする機能が欲しい
2. 投稿予約機能が欲しい(画面UIにも存在しない機能である)
3. 記事一覧取得[GET]にて画面UIにて削除した記事が返却される(仕様通りではないと思われる)
4. プロパティのis_sharedについて、動作確認を行ったが、どこの要素に効くパラメタなのか分からなかった

1については、2023/02/06 API提供済み。
2については、1が機能追加されることで、API利用側の制御にて解決できる。
3については、2023/02/06 修正済み。
4については、無料プレゼントURLの有効化フラグであることが分かった。

参考

https://bookers.tech/post/8ba5c8bb-f3a1-4e99-be1d-03ba0f72b324/

https://bookers.tech/post/14d26216-5844-4fd9-8031-5f9806db446d/

https://bookers.tech/post/9ac5fd7b-33f0-4775-a5f8-7ad8edd21d08/

https://bookers.tech/post/edf1cc28-82fd-4457-a139-a61e54165fe8/

https://bookers.tech/post/256507d0-c71b-4cf2-8dd0-47f439dec4d6/

https://bookers.tech/post/af13a3f0-8aae-45bb-9587-945b9b9d7908/

Discussion