論理の流刑地

地獄の底を、爆笑しながら闊歩する

選手の個人スタッツのデータベースをつくる by rvest&RSelenium

鉄は熱いうちに打て、ということで分析基盤をやる気のあるうちにつくる。
テーマや領域にかぎらず、大抵の分析は「分析可能なデータをつくる」工程に大部分の時間・労力が費やされる説あります。

Introduction

Jリーグをクラブ単位でデータ化することはあらかたできた。
ronri-rukeichi.hatenablog.com


ので、次にすることは、個人単位でのStatsをデータ化することである。

例によって、rvestによるデータ化をこころみていく。。。。。予定だったが、
対象のサイトがコンテンツを(Javascriptなどにより)動的生成している系のやつだったので、RSeleniumを使う必要がでてきた。
その学習記録もふくめた、備忘。

最終目標は、sofascoreの試合詳細ページ(例:名古屋vs清水)から個人の各種Statsをとってくることである。

◆参考URL

  1. vignettes
  2. reference
  3. [R]RSeleniumの環境構築(Windows) - Qiita
  4. [R][RSelenium/rvest]スクレイピングから某夢の国のクチコミを可視化してみた - Qiita ⇐良記事
  5. [翻訳] RSelenium vignette: RSeleniumの基本 - Qiita ⇐最重要

目標の設定

「何を実現したいか」、を先に決めることが学習の効率性を高めるためには肝要である。
ここでは、試合詳細のページ(例:ガンバvs名古屋 20/9/23)から出場選手の各統計指標を取ってくることを目標としよう。

なぜRSeleniumが必要かといえば、まずページを読み込んだ時の初期表示においては、以下のようにフォメ図が表示されているが、

f:id:ronri_rukeichi:20201006134121p:plain
出典:Sofascore

ここで、「Player Statistics」をクリックしないと、指標に関するtableが生成されないからである。
また、テーブルは「Summary」「Attack」など6種類に分かれているので、これも見出しをクリックしていかないと各種統計指標を取得できない。

したがって、以下のような手順でのScrapingのプログラムをかく必要がある。

  1. 試合詳細のURLにアクセス
  2. 「Player Statistics」をclick
  3. 各テーブルの見出しをclick
  4. 表示されたテーブルの内容をrvestで取得&データ化
  5. 3~4を繰り返す

下線部が、ブラウザの自動制御が必要なところとなる。ここにおいて、RSeleniumが必要となってくる。

実装(Rseleniumのとこだけ)

Seleniumサーバーは立ち上がっているとした前提でね。

初期化

library(rvest)
library(Rselenium)

clnt <- RSelenium::remoteDriver(port=4444L,browserName = "chrome") #Chromeで立ち上げる
clnt$open() #接続

これでChromeが立ち上がる。

クリックして表示をかえていく

##--ガンバvs名古屋の試合に移動--##
url1 <-  "https://www.sofascore.com/gamba-osaka-nagoya-grampus-eight/LmbsNmb"
clnt$navigate(url)

##--clickして「Player Statisticsを表示させる」--##
pstat_tag <-  clnt$findElements(using="css" , ".u-mB12 a+a.bfqsCw")[[1]]
pstat_tag$clickElement() #Clickして「Player Statistics」に移動
Sys.sleep(0.5) #0.5秒待機

##--6種類ある見出しを順番にclickしていく--##

click_tgts <- clnt$findElements(using="css" , "div.dtirhQ a.bfqsCw") #見出しのタグをまとめて取得
  for( i in seq_along( click_tgts)){
    click_tgt <- click_tgts[[i]]
    click_tgt$clickElement()
    Sys.sleep(0.3) #待機
 #---ここにrvestでの取得処理を入れる---#
  } #for

一応読み込みの時間を考慮して、0.3秒ずつの待機時間を挟んでいる。
例によってcssセレクタはselectorGadget(あるいはChromeの「検証」機能)で確認しとります。

実装(rvestで実際にテーブルを取得していく)

クリック等でお目当ての状態に遷移させたうえで、ページの情報を取得していくには、
getPageSource()でドキュメントを取得してから、rvestに渡すのが一番ラクだ。

今回の場合、上のクリックで表示されるテーブルを変えていくfooループのところに、以下の関数で書かれているような、tableをデータフレーム化して取得する処理を書いていくのがよい。

#お目あてのテーブルを表示させたうえで、remoteServerのオブジェクトをわたす
pTbl_get <- function(clnt){
  pdoc <- clnt$getPageSource()
  phtml <- read_html( pdoc[[1]])

  ### 対象のテーブルタグを探索sur
  tbl_node <- html_nodes( phtml , css ="table.dygnyR")
  tbl <- html_table( tbl_node[[1]], fill=NA, header=T)
  return(tbl)
} #function

すると、以下のようにrvestだけでは取得できないデータが取得している

> head(ptbl1$Attack,2)
#               + Shots on target Shots off target Shots blocked
#1 NA         Leandro               3                1             0
#2 NA Akihiro Hayashi               0                0             0
#  Dribble attempts (succ.) Notes Position Rating
#1                    2 (2)     -        F    7.9
#2                    0 (0)     -        G    7.4

あとは、分析しやすいように各指標を整形・変換したうえでdata frame化すればよい。

Conclusion

上の基本挙動に加え、データの整形処理*1等も加えた関数をつくったうえで実行してみる。

stat_df1 <-  get_PStat(clnt , url1)
head( stat_df1, 2)


# PlayerName Goals Assists Tackles Passes_All Passes_Suc Duels_All
# 1 Yosuke Ideguchi     0       1       2         70         65         3
# 2   Takashi Usami     1       0       0         14         13         3
# Duels_Suc gDuels_All gDuels_Suc aDuels_All aDuels_Suc Position
# 1         2          2          2          1          0        M
# 2         1          3          1          0          0        M
# Shots_onTgt Shots_offTgt Shots_blocked Dribbles_All Dribbles_Suc
# 1           1            1             0            0            0
# 2           2            0             0            0            0
# Clearances Interceptions Dribbles_Past Block_Shots Touches KeyPasses
# 1          0             3             0           0      84         3
# 2          0             0             0           0      21         0
# Crosses_All Crosses_Suc Longballs_All Longballs_Suc BoalLost
# 1           1           1             3             0        9
# 2           2           0             0             0        5
# Fouls_For Fouls_Against
# 1         1             0
# 2         1             1

出場した個人のStatsがうまく取れている。

まだ、

  1. 各ページのURLの取得・走査ルールをつくる
  2. 差分取得プログラムをつくる
  3. Football Labの方のデータと統合できるようにKey tableをつくる*2

などやるべきことはあるが、ひとまず目標は達成したといってよいだろう。



ACIDMAN - 「Rebirth」MV

Enjoy!!

*1:実際はここがめんどくさくて意外と工数かかったりする。が、丁寧にやらないとあとで分析しようと思った時に泣きをみる

*2:上のプログラムだとアルファベットの選手名しか分からないので、背番号や所属クラブの名前と照合できるようにする