Rで解析:B.LEAGUEの選手とクラブの成績詳細の取得例

Rの解析に役に立つ記事
スポンサーリンク

最近、日本のバスケットボールが面白いことに気が付きました。日本バスケット団体のB.LEAGUEのホームページを見ていたところ、各選手と各クラブの成績詳細のデータが公開されていました。

B.LEAGUE:https://www.bleague.jp/

B.LEAGUEのホームページから「各選手と各クラブの成績詳細のデータの取得」、「取得したデータをエクセルで保存」、「取得したデータから試合数8以上、得点数100以上の選手の3ポイントとフリースローの成功率の散布図の作成」のコマンド例を紹介します。

スクレイピングには「RSelenium」パッケージを使用しています。

さらに日本のバスケットが面白くなるような解析が広がればと思います。

各パッケージバージョンは記事作成時で最新。実行コマンドはwindows 11のR version 4.2.2で確認しています。

スポンサーリンク

実行コマンドの紹介

詳細はコマンド、各パッケージのヘルプを確認してください。

#必要パッケージの読み込み
#RSeleniumパッケージがなければインストール
if(!require("RSelenium", quietly = TRUE)){
  install.packages("RSelenium");require("RSelenium")
}
#tidyverseパッケージがなければインストール
if(!require("tidyverse", quietly = TRUE)){
  install.packages("tidyverse");require("tidyverse")
}
#openxlsxパッケージがなければインストール
if(!require("openxlsx", quietly = TRUE)){
  install.packages("openxlsx");require("openxlsx")
}
#cowplotパッケージがなければインストール
if(!require("cowplot", quietly = TRUE)){
  install.packages("cowplot");require("cowplot")
}
 
#seleniumサーバーを開始する
#初回は必要ファイルをダウンロードするので時間がかかる
StartSel <- rsDriver(browser = "chrome",
                     chromever = "107.0.5304.62",
                     verbose = TRUE)
 
###&#36984;&#25163;&#12392;&#12463;&#12521;&#12502;&#12398;&#25104;&#32318;&#35443;&#32048;&#12434;&#21462;&#24471;&#12377;&#12427;#####
#selenium&#12434;&#28310;&#20633;
SelGet <- StartSel[["client"]]
 
#&#21462;&#24471;&#24180;&#12434;&#25351;&#23450;
GetYear <- 2022
 
#&#36984;&#25163;&#12392;&#12463;&#12521;&#12502;&#12398;&#25104;&#32318;&#35443;&#32048;&#12398;URL&#12434;&#35373;&#23450;
SelGet$navigate(paste0("https://www.bleague.jp/stats/?tab=1&year=",
                       GetYear,"&target=player-b1&value=AveragePoints"))
 
#&#12418;&#12387;&#12392;&#35211;&#12427;&#12508;&#12479;&#12531;&#12434;&#25351;&#23450;
GetMotto <- SelGet$findElement(using = "css", "[class = 'btn']")
 
#&#12418;&#12387;&#12392;&#35211;&#12427;&#12508;&#12479;&#12531;&#12398;&#20307;&#35009;&#12434;&#21462;&#24471;
StyleMotto <- SelGet$findElement(using = "id", "player_b1_more")
 
#&#12456;&#12521;&#12540;&#26684;&#32013;&#22793;&#25968;
GetValue <- ""
 
#StyleMotto&#12395;display: none;&#12364;&#20986;&#12427;&#12414;&#12391;&#32368;&#12426;&#36820;&#12375;&#23455;&#34892;
while(!GetValue == "display: none;"){
 
  GetMotto$clickElement()
  GetValue <- StyleMotto$getElementAttribute("style")[[1]]
 
}
 
#html&#12395;&#22793;&#25563;
GetHtml <- XML::htmlParse(SelGet$getPageSource()[[1]])

#&#12486;&#12540;&#12502;&#12523;&#37096;&#20998;&#12434;&#25277;&#20986;
GetTable <- XML::readHTMLTable(GetHtml, encoding = "utf-8")
 
#&#36984;&#25163;&#12398;&#25104;&#32318;&#35443;&#32048;&#12434;&#21462;&#24471;&#12377;&#12427;
PlayerData <- tibble(GetTable[["player-b1"]]) %>%
  #&#38918;&#20301;&#21015;&#12391;"&#38918;&#20301;"&#12434;&#21547;&#12416;&#34892;&#12434;&#38500;&#22806;
  filter(!&#38918;&#20301; == "&#38918;&#20301;") %>%
  #&#35079;&#25968;&#31354;&#30333;&#12434;&#19968;&#12388;&#12395;&#32622;&#25563;&#12377;&#12427;
  #mutate("&#36984;&#25163;" = str_squish(&#36984;&#25163;)) %>%
  #&#36984;&#25163;&#21015;&#12363;&#12425;&#24773;&#22577;&#12434;&#20998;&#21106;
  mutate("&#36984;&#25163;&#21517;" = str_extract(&#36984;&#25163;, "^[^0-9#]+"),
         "&#32972;&#30058;&#21495;" = str_extract(&#36984;&#25163;, "[#|#\\d]+"),
         "&#12509;&#12472;&#12471;&#12519;&#12531;" = str_extract(&#36984;&#25163;, "[[:alpha:]/[:alpha:]]+$|[[:alpha:]]+$")) %>%
  select(&#38918;&#20301;, &#36984;&#25163;&#21517;, &#32972;&#30058;&#21495;, &#12509;&#12472;&#12471;&#12519;&#12531;, everything(), -&#36984;&#25163;) %>%
  mutate_if(is.character, str_trim)
 
#&#12481;&#12540;&#12512;&#12398;&#25104;&#32318;&#35443;&#32048;&#12434;&#21462;&#24471;&#12377;&#12427;
ClubB1Data <- tibble(GetTable[["club-b1"]]) %>%
  #&#35079;&#25968;&#31354;&#30333;&#12434;&#19968;&#12388;&#12395;&#32622;&#25563;&#12377;&#12427;
  mutate("&#12463;&#12521;&#12502;" = str_squish(&#12463;&#12521;&#12502;)) %>%
  #&#38918;&#20301;&#21015;&#12391;"&#38918;&#20301;"&#12434;&#21547;&#12416;&#34892;&#12434;&#38500;&#22806;
  separate(col = "&#12463;&#12521;&#12502;",
           into = c("&#12463;&#12521;&#12502;","&#12463;&#12521;&#12502;&#30053;&#21517;"),
           sep = " ", remove = TRUE)
 
 
#&#36984;&#25163;&#12392;&#12481;&#12540;&#12512;&#12398;&#25104;&#32318;&#35443;&#32048;&#12434;&#20316;&#26989;&#12501;&#12457;&#12523;&#12480;&#12395;&#12456;&#12463;&#12475;&#12523;&#12391;&#20986;&#21147;
#&#12527;&#12540;&#12463;&#12502;&#12483;&#12463;&#12398;&#20316;&#25104;:createWorkb&#12467;&#12510;&#12531;&#12489;
NewWb <- createWorkbook()
#&#12471;&#12540;&#12488;&#12434;&#36861;&#21152;
addWorksheet(wb = NewWb, sheetName = "PlayerData", tabColour = "red")
addWorksheet(wb = NewWb, sheetName = "ClubB1Data", tabColour = "blue")
#&#12487;&#12540;&#12479;&#12434;&#26360;&#12365;&#36796;&#12415;
writeData(wb = NewWb, sheet = 1, x = PlayerData)
writeData(wb = NewWb, sheet = 2, x = ClubB1Data)
#xlsx&#12501;&#12449;&#12452;&#12523;&#12391;&#20445;&#23384;
saveWorkbook(wb = NewWb, file = paste0(GetYear, "_BLeague.xlsx"),
             overwrite = TRUE)
 
#selenium&#12469;&#12540;&#12496;&#12540;&#12434;&#32066;&#20102;
SelGet$close()
StartSel[["server"]]$stop()
 
###&#35430;&#21512;&#25968;8&#20197;&#19978;,&#24471;&#28857;&#25968;100&#20197;&#19978;&#12398;&#36984;&#25163;&#12398;3&#12509;&#12452;&#12531;&#12488;&#12392;&#12501;&#12522;&#12540;&#12473;&#12525;&#12540;&#12398;&#25104;&#21151;&#29575;&#12398;&#25955;&#24067;&#22259;&#12434;&#20316;&#12427;#####
#&#12487;&#12540;&#12479;&#12398;&#25972;&#29702;
PlayerData %>%
  select("&#12463;&#12521;&#12502;", "G", "PTS", "&#36984;&#25163;&#21517;", "3FG%", 'FT%') %>%
  rename("Club" = '&#12463;&#12521;&#12502;',
         "Plyer" = '&#36984;&#25163;&#21517;',
         "TFG_Percent" = '3FG%',
         "FT_Percent" = 'FT%') %>%
  mutate("FT_Percent" = str_replace(FT_Percent, pattern = "%",
                                    replacement=""),
         "TFG_Percent" = str_replace(TFG_Percent, pattern = "%",
                                     replacement="")) %>%
  mutate("TFG_Percent" = as.integer(TFG_Percent),
         "FT_Percent" = as.integer(FT_Percent),
         "G" = as.integer(G),
         "PTS" = as.integer(PTS)) %>%
  filter(G >= 8 & PTS >= 100) -> PlotData
 
#&#20006;&#12409;&#12390;&#12503;&#12525;&#12483;&#12488;
ggplot(PlotData, aes(x = TFG_Percent, y = FT_Percent,
                     col = Club, label = Plyer)) +
  geom_text(show.legend =  FALSE) +
  ggtitle("&#36984;&#25163;&#21517;:&#35430;&#21512;&#25968;8&#20197;&#19978;,&#24471;&#28857;&#25968;100&#20197;&#19978;&#12398;&#36984;&#25163;\n3&#12509;&#12452;&#12531;&#12488;&#12392;&#12501;&#12522;&#12540;&#12473;&#12525;&#12540;&#12398;&#25104;&#21151;&#29575;") +
  labs(x = "3P&#12471;&#12517;&#12540;&#12488;&#25104;&#21151;&#29575;", y = "&#12501;&#12522;&#12540;&#12473;&#12525;&#12540;&#25104;&#21151;&#29575;") -> P1
 
ggplot(PlotData, aes(x = TFG_Percent, y = FT_Percent,
                     col = Club, label = Club)) +
  geom_text() +
  ggtitle("&#12463;&#12521;&#12502;&#21517;:&#35430;&#21512;&#25968;8&#20197;&#19978;,&#24471;&#28857;&#25968;100&#20197;&#19978;&#12398;&#36984;&#25163;\n3&#12509;&#12452;&#12531;&#12488;&#12392;&#12501;&#12522;&#12540;&#12473;&#12525;&#12540;&#12398;&#25104;&#21151;&#29575;") +
  labs(x = "3P&#12471;&#12517;&#12540;&#12488;&#25104;&#21151;&#29575;", y = "&#12501;&#12522;&#12540;&#12473;&#12525;&#12540;&#25104;&#21151;&#29575;") -> P2
 
#&#12503;&#12525;&#12483;&#12488;
cowplot::plot_grid(P1, P2, align = "h",
                   rel_widths = c(1, 1.5),
                   scale = 0.95)

出力例

・試合数8以上,得点数100以上の選手の3ポイントとフリースローの成功率の散布図


少しでも、あなたの解析が楽になりますように!!

タイトルとURLをコピーしました