見出し画像

【競馬】Python で JRA-VAN DataLab. のデータを取得する

Python で JV-Link を操作することにより、JRA-VAN DataLab. が提供する競馬データを取得することができます。
※ JV-Link は公式には Python に対応していません。全ての機能が正常に動作する保証は無いのでご注意下さい。

こちらの記事がとても参考になりました。ありがとうございます。

1. 動作環境

  • OS : Windows

どこまで古いバージョンで動作するかは分からないですが、Windows 10 以降であれば問題ないはずです。

私の使っている環境は

  • Windows 11 Home (64bit 版)

です。

2. JV-Link のインストール

こちらのページの [動作確認 (JV-Link)] のタブからインストーラーをダウンロードしてインストールおよび初期設定を行って下さい。
※ 使用するには JRA-VAN DataLab. の会員登録が必要です。

3. 32bit 版 Python のインストール

64bit 版 Python ではうまく動作しなかったので、32bit 版 Python を使用します。
32bit 版 Python 用のパッケージはメンテナンスされていないものが多いらしく、最早まともな分析環境を構築することすらままなりません。
PC に 1 つだけインストールする Python に 32bit 版を選択するのはお勧めしません。
私は pyenv を使って既存の 64bit 版 Python と共存させる形で 32bit 版 Python 3.7.9 をインストールしました。

4. インストールした Python のバージョン確認

python コマンドで REPL に入り、バージョンを確認します。

> python
Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:01:55) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
>

32bit 版の Python 3.7.9 がインストールできていることが分かりました。

5. pywin32 パッケージのインストール

Python で JV-Link を操作するために、pywin32 パッケージをインストールします。

> pip install pywin32

6. Python スクリプトの作成

JupyterLab か Jupyter Notebook を使いたかったのですが、32bit 版 Python ではパッケージのインストールがうまくいかず断念しました。(いくつかのバージョンで試してみましたが駄目でした。)

Python スクリプトファイルを作成して、それを実行するようにします。
下記スクリプトを sample1.py というファイル名で保存します。

import win32com.client


def main():
    race_names = ""

    JVLink1 = win32com.client.Dispatch("JVDTLab.JVLink")

    # JVLink初期化
    return_code = JVLink1.JVInit("UNKNOWN")

    # JVInitエラー処理
    if return_code != 0:
        print("JVInitエラー:", return_code)
        return

    # 速報系データの0B12を呼び出し
    # 日付は直近の土日を指定して下さい
    return_code = JVLink1.JVRTOpen("0B12", "20230430")

    # JVRTOpenエラー処理
    if return_code != 0:
        print("JVRTOpenエラー:", return_code)
        return

    return_code = 1
    while return_code != 0:
        return_code, buff, buff_size, file_name = JVLink1.JVRead("", 40000, "")

        # JVReadエラー処理
        if return_code < -1:
            print("JVReadエラー:", return_code)
            break

        if buff[0:2] == "RA":
            # レース名(英語)を抽出し末尾のスペースを除去
            race_name = buff[212:332].rstrip()
            if race_name != "":
                race_names += race_name + "\r\n"

    # レース名一覧を表示
    print(race_names)

    # JVLink 終了処理
    return_code = JVLink1.JVClose()


if __name__ == "__main__":
    main()

19 行目の

    return_code = JVLink1.JVRTOpen("0B12", "20230430")

の日付部分は直近の土日(中央競馬のレースが開催された日)を yyyymmdd 形式で指定して下さい。
※ このコードで取得している速報系データはレース後 1 週間程で配信されなくなるので、古い開催日を指定してもデータは取得できません。

7. 動作確認

下記コマンドで Python スクリプトを実行します。

> python sample1.py

メッセージボックスにレース名(英語)が表示されれば OK です。

レース開催が無い日や、古い開催日をコード内で指定している場合は下図のようなエラーが発生します。

8. 日本語データは文字化けする

今回はいままでの記事とは違い、英語のレース名を取得するようにしました。日本語データを取得しようとすると文字化けが発生するからです。

Python スクリプトの 37 行目の

            race_name = buff[212:332].rstrip()

            race_name = buff[32:92].rstrip()

に変更すると日本語のレース名を取得するようになりますが、実行すると

となってしまい、正しく日本語を表示できませんでした。
encode や decode を組み合わせていろいろやってみたんですが、解決できませんでした。
Python 2 系でも試してみましたが駄目でした。

JRA-VAN SDK に含まれる『JV-Linkインターフェース仕様書』には

JVRead は、内部で渡されたメモリを解放し、SJIS で開いたファイルを UNICODE 変換して新たに確保したメモリエリアに渡す処理をしている

と書かれており、これがヒントになるかも知れません。
解決方法を見つけた方がいらっしゃいましたら是非教えて下さい。

9. 実用性はあるか?

日本語の文字化けが解決できなかったとしても、日本語データを含まないオッズデータを取得するのに使えるかも知れません。

しかし、取得したデータを分析しようとすれば 32bit Python 内では完結するのが難しいのであまり実用性はないと思います。

いいなと思ったら応援しよう!