#前置き
スクレピングと言えばPythonだと思っていたのに、Rでも出来るじゃん!!ってなったので、自分でもやってみようと思います。これが出来れば色々応用が効くので。
まだ日本語の記事も多くはないので、まだ使ったことの無い人の参考になれば幸いです。
今回は、2017年4月に置ける明治安田生命J1リーグの結果を取得してみたいと思います。
#下準備
rvestパッケージを使えるようにしておきます。
install.packages("rvest", dep=TRUE)
library(rvest)
#データ取得先
試合結果は https://www.jleague.jp/match/search/j1/201704/ に載っています。最初に、アドレスを指定して、データを取得します。
#2017年04月のJ1の結果ページ取得
J1_2017_04 <- read_html("https://www.jleague.jp/match/search/j1/201704/")
#試合結果を取得する
htmlを読むと、クラス名"matchTable"というテーブルが開催日ごとにあり、その中に各試合のチーム名や点数を含むクラス名"gableTable"というテーブルが存在する、入れ子構造になってます。
まず手始めに、4月1日開催分の結果を取得してみましょう。 matchTable
が開催日順になっているので1番目を指定し、その中に含まれるクラス名"gameTable"を取り出して、最終的にhtml_table
関数でgameTableに含まれるテーブルから、それぞれの結果を取得します。
#結果取得 .matchTableごとに.gameTableを取得
matchTable_node <- html_nodes(J1_2017_04,".matchTable")
gameTable_node <- html_nodes(matchTable_node[1],".gameTable")
gameTable_table <- html_table(gameTable_node, fill=TRUE)
得られた結果は、下記のようなデータが入ったリストになってました。
head(gameTable_table, n=1)
#[[1]]
# X1 X2 X3 X4 X5
#1 仙台 0 試合終了 2 川崎F
このままだと扱いにくいのでデータフレームに整形します。
#データフレームに整形
length <- length(gameTable_table)
matchTable_table <- NULL
for(i in 1:length) {
matchTable_table <- rbind(matchTable_table, gameTable_table[[i]])
}
するとこんな感じに。
head(matchTable_table, n=3)
# X1 X2 X3 X4 X5
#1 仙台 0 試合終了 2 川崎F
#2 新潟 2 試合終了 3 G大阪
#3 広島 0 試合終了 2 柏
#開催日と節を追加する
それぞれの情報は、<div class=timeStamp>
タグ内の<h4>
タグと、<div class=leagAccTit>
タグ内の<h5>
タグにあったので、そこから取ってきます。
取ってきたらcbindで結合します。
#開催日と節を追加
timeStamp_node <- html_nodes(J1_2017_04,"div.timeStamp>h4")
timeStamp_text <- html_text(timeStamp_node[1])
leagAccTit_node <- html_nodes(J1_2017_04,"div.leagAccTit>h5")
leagAccTit_text <- html_text(leagAccTit_node[1])
matchTable_table2 <- cbind(rep(leagAccTit_text,times=length), rep(timeStamp_text, times=length), matchTable_table)
これで開催日が4月1日の結果と、節・日時が取得できました。
head(matchTable_table2, n=3)
# rep(leagAccTit_text, times = length) rep(timeStamp_text, times = length) X1 X2
#1 明治安田生命J1リーグ 第5節 2017年4月1日(土) 仙台 0
#2 明治安田生命J1リーグ 第5節 2017年4月1日(土) 新潟 2
#3 明治安田生命J1リーグ 第5節 2017年4月1日(土) 広島 0
# X3 X4 X5
#1 試合終了 2 川崎F
#2 試合終了 3 G大阪
#3 試合終了 2 柏
#ループを回して全取得
他の開催日の試合結果を得るために、上記をmacthTableの数だけループで回します。
最後にちょこっと列名を修正。
#ループを回す
matchTable_length <- length(matchTable_node)
resultTable <- NULL
for (i in 1:matchTable_length) {
gameTable_node <- html_nodes(matchTable_node[i],".gameTable")
gameTable_table <- html_table(gameTable_node, fill=TRUE)
matchTable_table <- NULL
gameTable_length <- length(gameTable_table)
for(j in 1:gameTable_length) {
matchTable_table <- rbind(matchTable_table, gameTable_table[[j]])
}
timeStamp_node <- html_nodes(J1_2017_04,"div.timeStamp>h4")
timeStamp_text <- html_text(timeStamp_node[i])
leagAccTit_node <- html_nodes(J1_2017_04,"div.leagAccTit>h5")
leagAccTit_text <- html_text(leagAccTit_node[i])
matchTable_table2 <- cbind(rep(leagAccTit_text,times=gameTable_length), rep(timeStamp_text, times=gameTable_length), matchTable_table)
resultTable <- rbind(resultTable, matchTable_table2)
}
colnames(resultTable) <- c("節","開催日","Home.Team","Home.Score","Finished","Away.Score","Away.Team")
resultTable
#完成です。
無事に、4月分の結果が取得できました。
head(resultTable, n=3)
# 節 開催日 Home.Team Home.Score Finished Away.Score
#1 明治安田生命J1リーグ 第5節 2017年4月1日(土) 仙台 0 試合終了 2
#2 明治安田生命J1リーグ 第5節 2017年4月1日(土) 新潟 2 試合終了 3
#3 明治安田生命J1リーグ 第5節 2017年4月1日(土) 広島 0 試合終了 2
# Away.Team
#1 川崎F
#2 G大阪
#3 柏
tail(resultTable, n=3)
# 節 開催日 Home.Team Home.Score Finished
#43 明治安田生命J1リーグ 第9節 2017年4月30日(日) 神戸 0 試合終了
#44 明治安田生命J1リーグ 第9節 2017年4月30日(日) 横浜FM 0 試合終了
#45 明治安田生命J1リーグ 第9節 2017年4月30日(日) C大阪 2 試合終了
# Away.Score Away.Team
#43 1 甲府
#44 1 G大阪
#45 0 川崎F