【スクレイピング】netkeibaからレース情報をスクレイピング|競馬AI作成:③-2

競馬AI

本記事の目的

本記事を読むことで、下記を実現できるようになります。

目的
  • 「netkeiba.com」からレース情報を取得する

レース情報

作業概要

以降では、下記の手順で「netkeiba.com」からレース情報を取得します。

  • ①レースIDリストを作成

    ※データ取得先のURLを作成するために必要となります。

  • ②「レース情報」を入手

①レースIDリスト作成

#ライブラリ
from datetime import datetime, timedelta

#メソッド:レースIDリスト作成
def create_race_id_list(start_date, end_date, area_list):
    
    days_diff = end_date - start_date
    date_list = [start_date + datetime.timedelta(days=i) for i in range(days_diff.days)]
    race_list = [str(i).zfill(2) for i in range(1, 13, 1)]
    race_id_list = []
    
    for date in date_list:
        for race in race_list:
            for area in area_list:
                race_id_list.append(date.strftime('%Y')\
                                    + area\
                                    + date.strftime('%m')\
                                    + date.strftime('%d')\
                                    + race)
                    
    return race_id_list
カテゴリ 変数 説明
引数 start_date datetime 取得開始日時
end_date datetime 取得終了日時
area_list list 取得対象の競馬場ID
戻り値 race_id_list list レースID

解説

レース情報のURLは、下記の構成になっています。

競馬場番号「06」は中山競馬場を表しています。

そのため、複数のレース情報を取得するには、まずレースIDリストを作成する必要があります。

実行結果

②レース情報を入手

#ライブラリ
from tqdm import tqdm
import urllib.request
from bs4 import BeautifulSoup
import time

#メソッド:レース情報を入手
def get_race_info(race_id_list):
    
    race_info_dict = {}
    
    for race_id in tqdm(race_id_list):#・・・・・・・・・・・・・・・・・・・・・・ ・・(※1)
        time.sleep(1)#・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・(※2)
        
        try:
            url = "https://race.netkeiba.com/race/result.html?race_id=" + race_id

            #WEBデータをpythonのメモリ上に取得
            html = urllib.request.urlopen(url).read()
            
            #WEBデータを解析・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・(※3)
            soup = BeautifulSoup(html, 'html.parser')
            div_01 = soup.find('div', class_='RaceData01').text
            div_02 = soup.find('div', class_='RaceData02').text

            #「レース種類」を抽出
            text = div_01.split('/')[1]
            if 'ダ' in text:
                race_type = 'ダート'
            elif '芝' in text:
                race_type = '芝'
            elif '障' in text:
                race_type = '障害'
                
            #「レース長」を抽出      
            race_len = int(text.split('m')[0][2:])
            
            #「天候」を抽出
            text = div_01.split('/')[2]
            if '曇' in text:
                weather = '曇'
            elif '晴' in text:
                weather = '晴'
            elif '雨' in text:
                weather = '雨'
            elif '小雨' in text:
                weather = '小雨'
            elif '小雪' in text:
                weather = '小雪'
            elif '雪' in text:
                weather = '雪'
            
            #「馬場状態」を抽出
            text = div_01.split('/')[3]
            if '良' in text:
                ground_state = '良'
            elif '稍重' in text:
                ground_state = '稍重'
            elif '重' in text:
                ground_state = '重'
            elif '不良' in text:
                ground_state = '不良'
            
            #「レースクラス」を抽出
            race_class = div_02.split('\n')[5]  
            
            #辞書型変数にレース情報を格納
            race_info_list = [race_type, race_len, weather, ground_state, race_class]
            race_info_dict[race_id] = race_info_list
            
        except Exception as e:
            print(e)
            
    return race_info_dict
カテゴリ 変数 説明
引数 rac_id_list list レースIDリスト
戻り値 race_info_dict dictionary レース情報

解説

プログレスバーを表示する(※1)

本処理では、「tqdm」を使用することでプログレスバーを表示させています。

処理状況が分かるようになるので、処理時間が長いループ処理の際に利用することをおすすめします。

for race_id in tqdm(race_id_list):#・・・・・・・・・・・・・・・・・・・・・・・・・・・・(※1)

時間間隔を設定する(※2)

スクレイピングする際には、Webサイトへの負荷を考慮する必要があります。

Webサーバーに負荷をかけると、他のユーザーがそのWebサイトを参照できなかったり、ひどい場合はサーバーが落ちてしまう場合もあります。
そのような迷惑をかけないためにも、クローラーは間隔をあけてWebサーバーにアクセスするといった対応が必要となります。最低1秒以上は間隔をあけるようにしましょう。

Pythonオンライン学習サービス PyQ

上記のように、スクレイピングする際には最低1秒以上は間隔を空けましょう。

 time.sleep(1)#・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・(※2)

レース情報を取得する(※3)

スクレイピングする際には、まずほしい情報のHTMLを確認します。

「欲しいデータを選択 → 右クリック → 検証」の順に操作することで、HTMLを確認できます。

そうすると、レース情報データは<div>タグにおける「class属性」が

  • RaceData01
  • RaceData02

であることが分かるので、この情報をもとにレース情報を取得します。

            #WEBデータを解析・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ (※3)
            soup = BeautifulSoup(html, 'html.parser')
            div_01 = soup.find('div', class_='RaceData01').text
            div_02 = soup.find('div', class_='RaceData02').text

実行結果

参考図書

本記事の内容は、以下の図書を参考にしています。

本書は、スクレイピング以外にも

  • データベースへの登録方法
  • 機械学習
  • ディープラーニング

等も内容に含まれています。

Python初心者にも理解しやすい内容になっているので、ぜひ参考にしてください。

本書の特徴
  • Python初心者でも理解できるくらい具体的に説明されている
  • ソースコードも併せて紹介されているため、コード記述の際に躓きづらい

次回の内容

次回は、「netkeiba.com」からレース結果を取得する方法を紹介します。

↓のリンクから飛べるようになっているので、ぜひ読んでみてください。

コメント

タイトルとURLをコピーしました