地方競馬をスクレイピングする方法を超わかりやすく解説

競馬Python

「中央競馬は土日しか開催してないから、平日も開催している地方競馬に参戦したい!」

と考えている競馬狂の皆さんこんにちは。

今回は、地方競馬の過去データを収集する方法について解説して行きます。

ちなみに中央競馬に関しましては、以前の記事で、JRA-VANを使用して競馬データを収集する方法や、netkeibaをPythonでスクレイピングする方法について解説しています。

地方競馬に関してですが、(筆者が試した範囲では)無料のJRA-VANでは過去データを取得することができませんでした。

つまり、現時点では地方競馬のデータを収集するためにはnetkeibaをスクレイピングするしかないようです。

そこで当記事では、筆者が作成したPythonを使って地方競馬をスクレイピングするコードを最後に載せています。

コードの中身はこちらの記事で解説している中央競馬のデータをスクレイピングしているコードと9割同じですので、ご確認ください。

残り1割の異なる点としては以下の2点になります。

・URLの作り方。

・地方競馬の場合、約1%程のレースで結果が未入力。

それぞれ詳しく解説していきます。

また競馬データの解析ではPythonのプログラミングスキルが必須になります。

Pythonの基本が完全には身についていない方は、以下の本で勉強するのがおすすめです。

特に、Pythonを使って機械学習の理論について学びたい方はこちらの本がおすすめです。

URLの作り方

netkeibaでは、地方競馬と中央競馬でURLの作り方の規則が異なります。

地方競馬のURLは例えばこんな感じです。

「https://db.netkeiba.com/race/202143102512/」

URLの後ろの方に「202143102512」という12桁の数字がありますね。

この数字が特定のレースと対応しているわけです。

対応関係は以下の通りです。

最初の「2021」が「西暦2021年」、次の「43」が「船橋競馬場」、次の「1025」が「10月25日」、次の「12」が「12レース」と対応しています。

ちなみに競馬場と数字の対応は以下の通りです。

したがってPythonでスクレイピングする際には、URLの「競馬場」と「月」と「日」と「レース」に対応する数字をFor構文で更新してやれば良いということです。

未入力のデータについて

地方競馬の場合、なぜかnetkeibaに結果が入力されていないレースが存在します。

これはどうしようもないので、スクレイピングしないことにしています。

以上の観点を考慮したPythonのコードは以下の通りです。

beautifulsoupとrequestsがインストールされていないとエラーになりますのでご注意ください。

コードの詳細な解説はこちらの記事で行なっています。

使い方としては、

・4行目にスクレイピングしたい年度を入力。

・174行目に保存先のパスを指定。

だけです。

帯広はばんえい競馬ですので、スクレイピングしませんでいた。

また、中央競馬とクラスの分け方が異なっているので、レースのクラスを反映する値として、1着賞金を記録しています。

終了とプリントされたら、ご自身が指定した保存先に「2021_chihou.csv」といった形のファイルが生成されています。

以上が地方競馬のデータをスクレイピングする方法です。

また、Pythonを使った機械学習を学びたい方は、以下の本で勉強するのがおすすめです。何事もまず基本ができていないと始まりませんよね。

他にもTwitterでAIを使った競馬予測をしていますので、フォローしていただけましたら幸いです。

Comments

  1. ori より:

    はじめまして
    競馬のデータが欲しくて参考という名の丸写しをさせてもらいました
    無事にスクレイピングできた年もあるのですが17年の笠松、19年の盛岡のおそらく3頭立てのレース後にエラーが出てしまいます

    上のコードの168行目と170行目で
    IndexError: list index out of range

    この場合どういった対処をすればいいのでしょうか?
    今はとりあえず17年の笠松と19年の盛岡だけ除外してスクレイピングしています

  2. まこちゃん より:

    3連単あたりでインデックスエラーになります。

    HTMLみて自分なりに治してみましたがうまく行きませんでした。
    よろしくお願いいたします。

    • 管理人 より:

      コメントありがとうございます。
      三連単がないパターンは「try」と「except」で取り除いているのですが、これは三連複もないパターンですかね、、、、
      ですが、これも「try」と「except」で取り除けると思います。
      時間があるときコードを修正しておきます。

  3. なう より:

    こんにちは。
    本日から急に以下エラーが出力されました。
    —————————————————————————
    IndexError Traceback (most recent call last)
    Cell In[25], line 128
    127 dis=str(var).split(“/”)[0].split(“>”)[1].split(“m”)[0][-4:]
    –> 128 con=str(var).split(“/”)[2].split(“:”)[1][1]
    129 wed=str(var).split(“/”)[1].split(“:”)[1][1]

    IndexError: list index out of range

    During handling of the above exception, another exception occurred:

    IndexError Traceback (most recent call last)
    Cell In[25], line 135
    133 rou=str(var).split(“/”)[0].split(“>”)[1][1]
    134 dis=str(var).split(“/”)[0].split(“>”)[1].split(“m”)[0][-4:]
    –> 135 con=str(var).split(“/”)[2].split(“:”)[1][1]
    136 wed=str(var).split(“/”)[1].split(“:”)[1][1]
    137 soup_smalltxt = soup.find_all(“p”,class_=”smalltxt”)

    IndexError: list index out of range

    昨日までは動いていましたので、何かしらnetkeiba.comのタグの修正が入った可能性があります。

    よろしくお願いいたします。

    • なう より:

      解決しました。
      やはりタグが変わっていましたので、以下に修正することで解消しました。

      #レースの情報
      try:
      var = soup_span[7]→[6]に修正