概要
競馬予想プログラムの一部。情報のスクレイピングの一部です。
レースの払い戻し情報。以下の部分の情報を取得してDataFrame化して返却します。
実は、このプログラムにはバグがあります。
同着を考慮していないのです。
競馬には同着があり得る。業務仕様、レア考慮漏れの良い例と思い反省もこめて
敢えてこの段階のソースを投稿しようと考えました。
サンプルソースコード
2023年のAJCCを取得している例です。
単独でnetkeibaログイン無しでも動作するようサンプルプログラムにしました。
# netkeibaのレース結果から払い戻し情報を取得するサンプルプログラム,BeautifulSoup,正規表現
import requests
from bs4 import BeautifulSoup
import pandas as pd
import re
def get_race_refund(raceid_str: str, result_url: str) -> pd.DataFrame:
#レース払い戻し情報の取得
keibasession = requests.session()
html = keibasession.get(result_url)
html.encoding = "EUC-JP"
soup = BeautifulSoup(html.text, "html.parser")
#払い戻し結果を取得
tables = soup.find_all('table', attrs={"class": "Payout_Detail_Table"})
for tbl in tables:
#2つのテーブルに分割取得されるので、順次取得
rows = tbl.find_all('tr')
#リストに展開(リスト内包表記)
data = [[col.text.replace('\n', '') for col in row.findAll(
['td', 'th'])] for row in rows]
#枠連は無い場合があるから、初期設定する。
frame_win = 0
#枠連が2頭しか無いバターンがあるから、初期設定する。(2頭の場合、諦める)
multiple_wins1 = 0
multiple_wins2 = 0
multiple_wins3 = 0
for refundkind in data:
if refundkind[0] == "単勝":
win = int(str(refundkind[2]).replace('円', '').replace(',', ''))
elif refundkind[0] == "複勝":
pattern = r'([,\d]+)円([,\d]+)円([,[\d]+)円.*'
result = re.match(pattern, refundkind[2])
if result: # none以外の場合
# group()で全文字を
multiple_wins1 = int(result.group(1).replace(',', ''))
multiple_wins2 = int(result.group(2).replace(',', ''))
multiple_wins3 = int(result.group(3).replace(',', ''))
elif refundkind[0] == "枠連":
frame_win = int(str(refundkind[2]).replace('円', '').replace(',', ''))
elif refundkind[0] == "馬連":
horse_win = int(str(refundkind[2]).replace('円', '').replace(',', ''))
elif refundkind[0] == "ワイド":
pattern = r'([,\d]+)円([,\d]+)円([,[\d]+)円.*'
result = re.match(pattern, refundkind[2])
if result: # none以外の場合
# group()で全文字を
wide_win1 = int(result.group(1).replace(',', ''))
wide_win2 = int(result.group(2).replace(',', ''))
wide_win3 = int(result.group(3).replace(',', ''))
elif refundkind[0] == "馬単":
horse_single = int(str(refundkind[2]).replace('円', '').replace(',', ''))
elif refundkind[0] == "3連複":
triple_muliti = int(str(refundkind[2]).replace('円', '').replace(',', ''))
elif refundkind[0] == "3連単":
triple_single = int(str(refundkind[2]).replace('円', '').replace(',', ''))
#refundと同じ列名のDataFremeの作成と返却
ret_refund_ds = pd.DataFrame({
'race_id': [raceid_str],
'win': [win],
'multiple_wins1': [multiple_wins1],
'multiple_wins2': [multiple_wins2],
'multiple_wins3': [multiple_wins3],
'frame_win': [frame_win],
'horse_win': [horse_win],
'wide_win1': [wide_win1],
'wide_win2': [wide_win2],
'wide_win3': [wide_win3],
'horse_single': [horse_single],
'triple_muliti': [triple_muliti],
'triple_single': [triple_single]
})
return ret_refund_ds
if __name__ == '__main__':
race_id_str = "202306010811"
url = "https://race.netkeiba.com/race/result.html?race_id=202306010811"
# 払戻情報の取得
refund_ds = get_race_refund(race_id_str, url)
print(refund_ds)