テイモン〜〜。Pythonよくわかんないよ〜〜。教えてよ〜〜〜。
Pythonなんて簡単な方なんだからggrks
ある日の結果一覧をCSVに書き出そう
前回はボートレース公式サイトのある日のある場の結果一覧ページから1日の全レースの2連単と3連単の結果と払戻金をPythonのライブラリpandasを使って簡単に取ってくる方法を見つけました。
でも、ただ表を出力するだけで、そこからさらにエクセルにコピペすることになるならボートレース公式サイトから直接該当の表をコピペすればいいだけですよね。
そこで、取ってきた表をCSVに書き出す、と言うところまでやってみました。
環境は今回もGoogle Colaboratoryです。
コードとしてはこんな感じです。
# ライブラリをインポート
import pandas as pd
# OSの機能を利用するパッケージ os をインポート
import os
# CSVを格納するディレクトリを決める
CSV_FILE_DIR = "drive/My Drive/teimon_practice/table/"
# URLを指定
url = 'https://www.boatrace.jp/owpc/pc/race/resultlist?jcd=03&hd=20201228'
dfs = pd.read_html(url)
#0番目のDataFrameを指定
df = dfs[0]
# インデックスを1行に成形
df.columns = ['レース','3連単組合せ','3連単払戻金','2連単組合せ','2連単払戻金','備考']
# CSVファイルを保存するフォルダを作成
os.makedirs(CSV_FILE_DIR, exist_ok=True)
# DataFrameをCSVで出力
df.to_csv('drive/My Drive/teimon_practice/table/to_csv_out.csv')
CSVファイルをどこかのディレクトリに保存する必要があるのでpandasに加えてosというライブラリもインポートしました。
これで指定のディレクトリにこんなcsvファイルが格納できました。
3連単組み合わせが日付形式で開かれてしまっていますが、エクセルで開く際にデータ形式を指定すればちゃんと「4-3-2」のように表示されます。
ただ、こちらはGoogleスプレッドシート上で簡易的に開いた状態なのでいい感じに見えていすが、エクセルで開くと文字化けしてしまっており、もう少し綺麗にする必要があります。
場と日付部分をわかりやすくしてみた
上で書いたように、このままだと文字化けしちゃいますし、このコードを使い回す場合、変更するのは日付と場のコードだからその部分をわかりやすくしたいと思い、少し書き換えました。
# ライブラリをインポート
import pandas as pd
# OSの機能を利用するパッケージ os をインポート
import os
# CSVを格納するディレクトリを決める
CSV_FILE_DIR = "drive/My Drive/teimon_practice/table/"
# URLを指定
# URLの固定部分
FIXED_URL = 'https://www.boatrace.jp/owpc/pc/race/resultlist?jcd='
# 場コード 江戸川は03
PLACE_NO = '03'
# 日付をYYYYMMDDで指定
DATE_NO = '20201228'
dfs = pd.read_html(FIXED_URL + PLACE_NO + "&hd=" + DATE_NO)
#0番目のDataFrameを指定
df = dfs[0]
# インデックスを1行に成形
df.columns = ['レース','3連単組合せ','3連単払戻金','2連単組合せ','2連単払戻金','備考']
# CSVファイルを保存するフォルダを作成
os.makedirs(CSV_FILE_DIR, exist_ok=True)
# ファイル名を場コード_日付.csvかつshift_jisに文字コード変換してCSV出力
df.to_csv( CSV_FILE_DIR + PLACE_NO + "_" + DATE_NO + ".csv" , encoding="shift_jis")
場コードと日付を指定したらデータを取ってくるURLも書き出すCSVのファイル名もつけられるのでコードの可変部分が
PLACE_NO = ’03’
DATE_NO = ‘20201228’
だけになりました。
でも一節間全部ダウンロードしたいとなると日付を何回も変えて実行しなきゃいけないのか……。
指定した複数の日程の結果を一気にCSV化
今回練習に使った江戸川の「第43回京葉賞 トータリゼータエンジニアリング杯」は12/24〜28の5日間開催。この節間の全部の結果を出力したいと思った場合、5回同じプログラムを実行するのは非効率。
そこで、まだ慣れないfor文を使って指定した期間分のCSVを出力してみました。
# pandasライブラリをインポート
import pandas as pd
# OSの機能を利用するパッケージ os をインポート
import os
from os import makedirs
# 時間を制御する time モジュールをインポート
from time import sleep
# 日付を扱うための datetime モジュールをインポート
from datetime import datetime as dt
from datetime import timedelta as td
# CSVファイルを保存するフォルダを作成
os.makedirs(CSV_FILE_DIR, exist_ok=True)
# CSVを格納するディレクトリを決める
CSV_FILE_DIR = "drive/My Drive/teimon_practice/table/"
# 開始日と終了日を指定(YYYY-MM-DD)
START_DATE = "2020-12-24"
END_DATE = "2020-12-28"
# 開始日と終了日を日付型に変換して格納
start_date = dt.strptime(START_DATE, '%Y-%m-%d')
end_date = dt.strptime(END_DATE, '%Y-%m-%d')
# 日付の差から期間を計算
days_num = (end_date - start_date).days + 1
# 日付リストを格納する変数
date_list = []
# 日付リストを生成
for i in range(days_num):
# 開始日から日付を順に取得
target_date = start_date + td(days=i)
# 日付型を文字列に変換してリストに格納(YYYYMMDD)
date_list.append(target_date.strftime("%Y%m%d"))
# URLの固定部分を指定
FIXED_URL = "https://www.boatrace.jp/owpc/pc/race/resultlist?jcd="
# 場コードを指定
PLACE_NO = '03'
# URL生成とダウンロード
for date in date_list:
# データを読みに行くURLを指定
dfs = pd.read_html(FIXED_URL + PLACE_NO + "&hd=" + date )
# 0番目のDataFrameを指定
df = dfs[0]
# インデックスを1行に成形
df.columns = ['レース','3連単組合せ','3連単払戻金','2連単組合せ','2連単払戻金','備考']
# ファイル名を場コード_日付.csvかつshift_jisに文字コード変換してCSV出力
df.to_csv( CSV_FILE_DIR + PLACE_NO + "_" + date + ".csv" , encoding="shift_jis")
# リクエスト間隔を指定(秒) ※サーバに負荷をかけないよう3秒以上を推奨
INTERVAL = 3
日付をリスト化する方法は過去の「コラボでGO!(3)」でやったものです。
これでこのように5日分の「場コード_日付.csv」というCSVファイルができました。
ブラッシュアップが必要な点
今回とりたかった一節のデータ取得は簡単にできましたが、もうちょっとこのコードは綺麗にした方が良さそうです。具体的には…
・指定した日付で開催がなかった場合などのエラー処理
・csvに書き出しただけだといつ出力が終了したのかわからないので作業終了の合図を入れる
・場コードを調べるのが面倒なので場コードのマスターデータを作って、それを参照するようなことができたほうがより便利かも
このあたりは今後の宿題にしたいと思います。
「コラボでGO」reference
Google Colaboratory環境設定はこちら↓
指定の日付の期間繰り返しのfor文↓
今回のようなひとつの場の一節とかではなく、一定期間の全場、全レースのデータを取ってくるならこちらの方法の方がオススメ
pandasに手を出した前回の記事↓