25行で大谷さんの2021年シーズンの毎試合の成績をスクレイピングする
9月も終わり、メジャーリーグ、プロ野球も終盤です。
野球のデータとなると年単位などある程度データ数が必要で、データの取り方も年単位の成績データで持つことが多いです。
しかし、毎日の試合の成績をデータとして持ちたい、そこからデータを加工したいと言うこともあると思います。
今回は、今シーズン、9月8日時点でホームラン数トップを走って大活躍の大谷選手の2021年の毎試合の成績をスクレイピングします。
(コードはホームページからのデータから取りにかかるので、最新のデータが取ることができます。)
スクレイピングのコードは25行です。
この25行で今シーズンの毎試合の成績を取得することができます。
スクレイピングするサイト
スクレイピングするサイトは以下のサイトになります。
このサイトは月ごとにテーブルが分けられています。
この分けられたデータを繋げて一つのテーブルにしていきます。
スクレイピングコード
今回の全体コードになります。
スクレイピングの関数を作り、URLを入力に関数を実行。
関数実行結果はデータフレーム形式にして取得し、最後にcsv形式で出力します。
import pandas as pd
import warnings
warnings.simplefilter("ignore")
def scrape(url):
df = pd.DataFrame()
data = pd.read_html(url)
for i in range(3,len(data)):
d=data[i]
d.dropna(inplace=True)
d = d[:-1]
df = pd.concat([df,d])
df.reset_index(inplace=True,drop=True)
df.reset_index(inplace=True)
df['日付']=pd.to_datetime('2021' + '/' + df['日付'],format='%Y/%m/%d')
df.rename(columns={'index':'試合数'},inplace=True)
df['試合数']=df['試合数']+1
return df
if __name__ == '__main__':
url = 'https://baseball.yahoo.co.jp/mlb/teams/player/fielder/stats/727378'
df = scrape(url)
df.to_csv('ootani_san_season2021.csv',index=False)
関数のコードを説明
関数は空白を抜いて14行です。
def scrape(url):
df = pd.DataFrame()
data = pd.read_html(url)
for i in range(3,len(data)):
d=data[i]
d.dropna(inplace=True)
d = d[:-1]
df = pd.concat([df,d])
df.reset_index(inplace=True,drop=True)
df.reset_index(inplace=True)
df['日付']=pd.to_datetime('2021' + '/' + df['日付'],format='%Y/%m/%d')
df.rename(columns={'index':'試合数'},inplace=True)
df['試合数']=df['試合数']+1
return df
1行目はdefでscrapeという関数を作っていきます。
かっこの中は宣言時に入力する変数を表します。
urlという変数にデータのあるサイトのURLを入力してscrape関数を処理していきます。
def scrape(url):
初期化部分
変数を初期化します。
dfにデータフレーム型を代入しておきます。
これで、データフレームからの処理を扱うことができます。
dataにはurl先のテーブル形式になっている情報をリスト形式でと取り出され、格納されます。
df = pd.DataFrame()
data = pd.read_html(url)
for文の処理
続いてfor文の処理です。
今回のスプレイピングするサイトで欲しいデータはリストの4番目のdata[3]に格納されているデータからになります。
そのため、forの範囲は3からdataリストに格納されている最後までのデータになります。
月毎にテーブルがまとめられているため、複数のデータを加工して結合していくことが必要です。
forのループ処理の中身はまずdata[i]よりリストに入っている成績データ取り出します。
dropnaでNULLデータを除去します。
これは、このデータの特徴で下から2番目にNULLデータとなっているためです。
各データの末尾は月の集計地になっているためd[:-1]で末尾を削ります。
そして、dfにデータを縦に結合していきます。
for i in range(3,len(data)):
d=data[i]
d.dropna(inplace=True)
d = d[:-1]
df = pd.concat([df,d])
結合後の処理
結合した後、データを仕上げていきます。
まず、indexの番号が重複しているので、reset_indexでindexの値をリセットし、古いindexはいらないので、drop=Trueで削除します。
二回目のreset_indexで列にindex列を作ります。
下記3行目では日付のデータを2021-07-01の形として持ちます。
4行目ではindex列の名前を試合数に変更します。
5行目で試合数にしたindexの値は0から始まるので1足して、何試合目か正確な値になります。
最後にreturnで返して終了です。
df.reset_index(inplace=True,drop=True)
df.reset_index(inplace=True)
df['日付']=pd.to_datetime('2021' + '/' + df['日付'],format='%Y/%m/%d')
df.rename(columns={'index':'試合数'},inplace=True)
df['試合数']=df['試合数']+1
return df
この記事が参加している募集
よろしければサポートをよろしくお願いします。サポートいただいた資金は活動費に使わせていただきます。