各選手の先発ポジションを取得する
ほしいもの
過去記事などで触れたようにSofaScoreから各選手の試合別スタッツは取得できる。
ronri-rukeichi.hatenablog.com
だが、若干分析上不便であるのが、ポジションがGK/DF/FW/MFの4区分でしか取得*1できないことである。
集計・グループ分けしてポジション別に比較をしたい、となったときCBとSBがごっちゃになったりボランチとトップ下とSHが一緒くたになるのは都合が悪い。
そこで活用できるのがFootBoolLABの選手別ページ(例:森下の2021年版となる)
上のように、その選手の先発ポジションの分布が年別に表示されている。
このページを見れば、ある選手がある年にSBで何試合、CBで何試合出たのかといったことが分かる。
このページからのデータ取得を試みる
How to
個別選手について
先発ポジ分布図について、Google Chromeの検証ツールをみて構造を確認すると、以下のように表示されている。
dlタグ配下のdtタグがポジション名を、ddタグが先発試合数を表わす
ということで、以下のコードのような関数をかけば取得できる
getPosition <- function( url ){ tgt_pg <- read_html( url) #Position情報を含むNodeを検出する pos_nodes <- html_nodes(tgt_pg, css = ".playerPos dl") pos_info <- lapply( pos_nodes , function(pos_node){ pos_name <- pos_node %>>% html_node("dt") %>>% html_text() pos_n <- pos_node %>>% html_node("dd") %>>% html_text() return( data.frame( Name = pos_name , N = pos_n)) }) ret_df <- do.call( bind_rows , args = pos_info) return(ret_df) } #func #森下選手のURL mori_url <- "https://www.football-lab.jp/player/1629426/?year=2021" #森下選手のポジション分布を取得 mori_pos <- getPosition(mori_url)
実際に、データは以下のような形で取得できる。
クラブ単位での取得
さて、最終的にはこれを全選手について取得したデータベースを作りたい、というのが目指すところである。
各クラブ別に所属選手を全取得したDBを自動的に生成できるようにすれば、リーグ全体のDBも容易に作成できる。
方針としては、クラブごとのサマリページ(例:名古屋のページ)から
各選手ページへのリンクを取得し、そこから先ほどの関数を適用して選手別データをひろってくる。
getClubPos <- function(club_name, year = 2021){ #対象URLを取得 tgt_url <- paste0( "https://www.football-lab.jp/" ,club_name,"/?year=", year) cat(tgt_url) clb_page <- read_html( tgt_url) #選手名, 背番号, 個別ページへのリンクを取得 player_links <- html_nodes(clb_page,css = ".statsTbl10 a") %>>% sapply( function(x){html_attr( x, name= "href")}) player_names <- html_nodes(clb_page , css = ".statsTbl10 a") %>>% sapply( html_text) player_no <- html_nodes(clb_page ,css = ".statsTbl10 tr td:first-child+td") %>% sapply( html_text) %>>% as.numeric #選手ごとのループを回す player_dfs <- lapply( player_links , function(p_chr){ full_url <- paste0( "https://www.football-lab.jp", p_chr, "?year=", year) player_df <- getPosition( full_url) #タテからヨコに df_w <- pivot_wider( player_df ,names_from= "Name", values_from="N") return(df_w) } ) #player_dfs #横になったものをタテにつなげる ret_df <- do.call(bind_rows , args = player_dfs ) #選手名、背番号の列を追加 ret_df <- data.frame(PlayerName = player_names , ShirtNo = player_no ) %>>% bind_cols( ret_df) return( ret_df) } #function ngePosInfo <- getClubPos("nago")
Hadley神が創りし神関数であるtidyr::pivot_wider()を利用して、タテからヨコにデータを溶かしているのが肝です。
確認すると、以下のような形でデータができている
あとは、J1の全チームに同じ処理を回して、タテにつなげればよい。
これで、「SBとして15試合以上先発している選手」どうしの比較などができるようになった。
Enjoy!!