21
38

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Pythonで競馬サイトWebスクレイピング

Last updated at Posted at 2020-05-03

PythonでWebスクレイピングする方法

この記事について

何番煎じになるか分かりませんが、競馬サイトの情報をCSV形式に落とし込む方法について記載していきます。
使用する言語はPython 3.6、環境はJupyter Notebookを使用しています。

筆者はPythonは不慣れなため、冗長コードやもっとスマートな手法があるかと思います。
しかし、今回は綺麗なコードを作ることが目的ではないので、今後の改善点と認識しつつも良しとしています。

スクレイピング先

以下のサイトから情報を抜出します。
サイト名:netkeiba.com (https://www.netkeiba.com/?rf=logo)

# URL生成のための事前知識

netkeiba.comでは、レースごとにWebページが存在します。
このWebページのURLは以下のルールで決められています。

東京競馬場で2020年5月3日に開催された2回 東京 4日目 第1レースを例にして当てはめていきます。

  • 開催年:2020(=2020年) 
  • 競馬場コード:05(=東京)
  • 開催回数:02(=2回)
  • 日数:04(=4日目)
  • レース数:01(=第1レース)
競馬場名 競馬場コード
札幌 01
函館 02
福島 03
新潟 04
東京 05
中山 06
中京 07
京都 08
阪神 09
小倉 10

上記を当てはめると以下のようになります。
https://race.netkeiba.com/race/result.html?race_id=202005020401&rf=race_list

URL生成~情報取得(コード)

URL生成~情報取得までのコードです。

web1.ipynb
# -*- coding: utf-8 -*- 
import csv
import requests
import codecs
import time
from datetime import datetime as dt
from collections import Counter
from bs4 import BeautifulSoup
import re
import pandas

race_date ="2020"
race_course_num="06"
race_info ="03"
race_count ="05"
race_no="01"
url = "https://race.netkeiba.com/race/result.html?race_id="+race_date+race_course_num+race_info+race_count+race_no+"&rf=race_list"

# 該当URLのデータをHTML形式で取得
race_html=requests.get(url)
race_html.encoding = race_html.apparent_encoding  
race_soup=BeautifulSoup(race_html.text,'html.parser')
print(url)

上記を実行すると、生成されたURLが表示されます。

表の取得(コード)

取得したHTMLテキストから表を取得するコードになります。
(上記コードに追記)

web1.ipynb
# レース表だけを取得して保存
HorseList = race_soup.find_all("tr",class_="HorseList")

# レース表の整形
# レース表を入れるリストを作成
Race_lists = []
# 表の横列の数=15("着順,枠,馬番,馬名,性齢,斤量,騎手,タイム,着差,人気,単勝オッズ,後3F,コーナー通過順,厩舎,馬体重(増減))
Race_row = 15

# 出馬数をカウント
uma_num = len(HorseList)

# 無駄な文字列を取り除いてリストへ格納
for i in range(uma_num):
    Race_lists.insert(1+i, HorseList[i])
    
    Race_lists[i] = re.sub(r"\n","",str(Race_lists[i]))
    Race_lists[i] = re.sub(r" ","",str(Race_lists[i]))
    Race_lists[i] = re.sub(r"</td>",",",str(Race_lists[i]))
    Race_lists[i] = re.sub(r"<[^>]*?>","",str(Race_lists[i]))
    Race_lists[i] = re.sub(r"\[","",str(Race_lists[i]))
    Race_lists[i] = re.sub(r"\]","",str(Race_lists[i]))
    print(Race_lists[i])

上記を実行すると、以下のように出力されます。
 1,1,1,レッドカルム,牝3,54.0,石橋脩,1:25.7,,3,4.6,37.1,,美浦奥村武,512(-4),
 2,6,12,サンキーウエスト,牝3,54.0,岩部,1:25.7,ハナ,2,3.2,36.5,,美浦萱野,442(-8),
 (以下略)

その他の表も多少の違いはあれど、似たような手順で取得できます。

CSV形式で保存(コード)

ほしい情報が取得できたので、CSVファイルで保存します。
(上記コードに追記)

web1.ipynb
# csvを開く
out=codecs.open("./this_race_table"+race_date+race_course_num+race_info+race_count+race_no+".csv","w")
# 今回はわかりやすくするためにCSV内に列名を記載する.(本当は必要ないので注意)
out.write("着順,枠,馬番,馬名,性齢,斤量,騎手,タイム,着差,人気,単勝オッズ,後3F,コーナー通過順,厩舎,馬体重(増減)\n")

# レース表リストの中身をcsvに記入していく
for i in range(uma_num):
    out.write(str(Race_lists[i]+"\n")) 
    
out.close()

上記を実行すると、ソースコードファイルが存在するフォルダにCSVが作成されます。

以上でスクレイピングは終了です。

その他

Librahack事件に代表されるように、Webスクレイピング(クローラ)が違法となる場合もありますので注意してください。

21
38
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
38

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?