こんにちは
悟です。(@rxf7oqjSU4v473O)
今回はPythonでスクレイピングをしていきます。
野球のデータの中でも最も一般的な選手の年次データをスクレイピングし、オリジナルのデータベースを作成したいと思います。
私にはデータベース周りの知識が乏しいので、今回はExcelデータに落とします。
Pythonも初心者ですので、記事執筆を通じて野球アナリストへ近づいていけたらと思います。
目次
全体の流れ
非効率な点や至らない点も多数ありますが、今の実力的にはこれが限界です。
とりあえずアウトプットが大切だろうということで、全体の流れを示します。
- Webサイトへアクセス
- urlを取得し、2007年から2020年までループで回す
- それぞれの年度でCSVファイルを作成
- 全てのCSVファイルを合成
- チームごとのCSVファイルを出力
データが置かれているURLを取得する(io.html.read_html)
まずはデータを取得します。
今回、利用させていただいたサイトは、プロ野球データFreakさんです。
取得対照したURLは、いい加減な利用を防ぐためコード内では削除しています。
このコードを使う人は、URLを該当箇所に入れて利用してください。
サイトURLを取得した後は、そこから表データを取得します。
io.html.read_html(“URL”) を使うことで、URL内にある表形式のデータを取得できます。
また、io.html.read_html(“URL”)[表番号] でn番目の表を取得できますので、表が沢山あるサイトなどはここをいじって調整します。
# -------------------------------------投手のデータを一括で取得します------------------------
import numpy
import pandas as pd
#import matplotlib.pylab as plt
#urlをリスト形式で取得
df_all = []
#各要素に各年のデータが入る(執筆時点では2020年が最新)
# 2020年から2008年まで
years = range(20,8,-1)
urls = []
#URLを入力:最新年度だけ命名規則が違う
for year in years:
if(year==20):
urls.append('####サイトのULRを入力してください。######')
else:
# http://baseball-data.com/'+ "{0:02d}".format(year)+'/stats/pitcher-all/era-1.html
urls.append('#####')
year=20
#--------------------------データをURLから取得-------------------------------------------
for url in urls:
print('取得URL:'+url)
df = pd.io.html.read_html(url)
df = df[0]
df_all.append(df)
year=year - 1
file_path="new_" + str(year)+"_npb_pichar.csv"
df.to_csv(file_path,encoding="cp932",index=None)

取得したデータを年次ごとにまとめてCSVファイルに出力(Excelも可)
データを取得したら、CSVファイルに出力しましょう。
その前に、取得した表を見ると「順位」など不要なデータが入っていることがわかります。
それらをまずは削除し、その後各年度ごとに出力します。
df.to_csv(“ファイルパス”) を用いてます。
df_all = []
year = 20
for url in urls:
year=year -1
file_path= "new_" + str(year)+"_npb_pichar.csv"
df=pd.read_csv(file_path,encoding="cp932")
df = df.drop([0])
df["year"] = str(20) + str(year)
df_all.append(df)
print('読み込んだファイル:'+file_path)
df.to_csv(file_path,encoding="cp932",index=None)

せっかくなので、チーム→選手名→年度でソートを掛けておきます。
これで大雑把ではありますが、全データを取得できたことを確認できます。
df_result = pd.DataFrame(df_result)
del df_result["順位"]
df_result = df_result.sort_values(["チーム","選手名","year"])
df_result

チームごとにCSVファイルを出力
各年度ごとにファイルはできましたが、現状のファイルでは同じ年の中でしか比較ができません。
そこで、2007年から2019年までのデータを1つのファイルにまとめた後、チームごとに出力してみることにします。
そうすれば、年度をまたいだ比較が可能になります。
# チームごとのCSVファイルを作成する
for team , sdf in df.groupby('チーム'):
file_path = team + "_pichar.csv"
print(i)
print(sdf)
sdf.to_csv(file_path,encoding="cp932",index = False,columns = ind_list)
実行したファイルの中に、チームごとのCSVファイルが出力されます。
現状では、これ移行の分析はExcelでどうぞ…となってしまいます。
おまけ NPBの選手名簿を作る
成績にはあまり関係ありませんが、選手の年齢や年俸などのデータを取ってみたいと思います。
単純な成績の比較に加えて、チーム内の年齢構成などが分かればより深い分析になるはずです。
# 選手名を重複なく抽出し、CSVファイルを作成
df_all = []
name_list = []
dic = {}
for year in range(19,8, -1):
file_path="new_" + str(year)+"_npb_personaldata.csv"
df = pd.read_csv(file_path,encoding="cp932")
df = df.drop([0])
for i in range(1, len(df)):
player_name = df['選手名'][i]
name_list.append(player_name)
# 重複を削除する
name_list = set(name_list)
file_path="npb_personaldata_name.csv"
name_list = pd.DataFrame(name_list,columns=["選手名"])
name_list.to_csv(file_path,encoding="cp932",index = None)
df_name = pd.read_csv("npb_personaldata_name.csv", encoding = "cp932")
df_name
df_result = []
# 選手名のリストをインポート
#print(df_name["選手名"][i])
# 年度ごとのファイルをインポート
for year in range(19,8, -1):
file_path="new_" + str(year)+"_npb_personaldata.csv"
df = pd.read_csv(file_path,encoding="cp932")
for i in range(1, len(df_name)):
player_name = df_name['選手名'][i]
for j in range(1, len(df)):
if player_name == df['選手名'][j]:
# print(df[player_name])
df_result.append(df.loc[j])
break
else:
continue
print(str(year) + player_name + "のデータ抽出が終わりました")

まとめ
Pythonを使って、野球データのスクレイピングを行いました。
年次データ程度では、真新しい分析はできませんので、今後はもう少し細かいデータの取得や分析を目指していこうと思います。
最後に、この記事でやったことのおさらいです。
- Webサイトへアクセス
- urlを取得し、2007年から2020年までループで回す
- それぞれの年度でCSVファイルを作成
- 全てのCSVファイルを合成
- チームごとのCSVファイルを出力