はじめに
この記事は、自身で製作しWeb公開にまで至ったボートレース3連単予測サイト「きょう、ていの良い予想は当たるだろうか」の内部コード解説となります。今回はウェブスクレイピングに関してまとめていきます。
※コードの書き方は我流なので、アドバイスいただけると有り難いです。
どんな情報が欲しいか、それをどこから頂くか
私が作りたいのは機械学習によるボートレースの3連単予想サイトなので、学習データとして、過去のレース結果をなんとか入手したいです。
最低限欲しい情報としては、、
- 競艇場
- 選手名
- Lane情報
- レース結果
- レースが行われた日付
ですかね。その他に欲しい情報は
- 第何レースか
- その日の天気
- モーター情報
などでした。最近のボートレース公式HPはデータもきちんと整備されており、過去のレース結果も参照することができます。
今回は、ここから学習データの大元となるレース結果を取得していきたいと思います!
URL構造を把握する
ボートレースの事前知識として、基本的に365日、24競艇場の中の幾つかの競艇場でレースが行われています。
そこで、URL構造を把握した後はレース情報を希望日数×24競艇場分取得することにしました。(レースが行われなかった場合は処理をスキップする)
URL構造を把握し、以下のようにしてURLが入った箱を用意しました。
コード内では2020/6/22のみのデータを取得していますが、year, month, dayのリストを増やしていけば、その他の日付のURLも取得できるようなイメージです。
import pandas as pd
import numpy as np
list = []
year = ['2020']
month = ['06']
day = ['22']
site = ['01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24']
for i in year:
for j in month:
for k in day:
for l in site:
list.append("url name is described here")
ボートレース結果を取得する!
こちらがそのコードとなります。
スクレイピングをする際には相手側のWebサーバーに負荷をかけないよう、一定時間を必ず設けるようにしましょう。
import requests
from time import sleep
from bs4 import BeautifulSoup
path_w = 'bs_2020_0622.txt'
list_errorlog = [] #その日試合がなかった競艇場をメモる、一応。
for m in range(len(list)):
try:
res = requests.get(list[m])
res.encoding = res.apparent_encoding
res.raise_for_status()
with open(path_w, mode='a', encoding='utf-8') as f:
txt = res.text
soup = BeautifulSoup(txt)
f.writelines(soup.get_text())
sleep(5) #消さない!
except:
sleep(5) #消さない!
list_errorlog.append(list[m]+"is not existing")
print(list_errorlog)
このコードでは
- ページにアクセス→テキストデータを取得し.txtに記入→5秒あけて繰り返す
- try catchによりWebページが存在しない(=レースがない)場合はスキップするように処理
を行なっています。参照先がかなりシンプルな構成なのでこれでいけますが、もっと凝ったページだとHTMLタグを上手く絞ってスクレイピングする必要があると思います。
取得結果がこちら
いい感じですね。次回はこのtextデータを機械学習が行えるようなDataFrame形式に変換していきたいと思います。
う〜ん、スクレイピングってすごい。(流行乗り遅れ感はありますが..)
最後に
- Webスクレイピングを行うにあたり、公式ホームページサイトポリシーを一読しました。
- また、スクレイピング せずとも上記のようなテキストデータは公式サイトからダウンロード可能です(爆)