見出し画像

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


ここから先は

167字 / 3ファイル
この記事のみ ¥ 100

この記事が参加している募集

野球が好き

よろしければサポートをよろしくお願いします。サポートいただいた資金は活動費に使わせていただきます。