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生成~情報取得までのコードです。
# -*- 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テキストから表を取得するコードになります。
(上記コードに追記)
# レース表だけを取得して保存
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ファイルで保存します。
(上記コードに追記)
# 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スクレイピング(クローラ)が違法となる場合もありますので注意してください。