Rで競馬データをスクレイピング :step2コード

R

netkeibaのサイトから競馬データを取得するためのステップは以下の通り。

  1. 入手したい日付(年、月)のカレンダーのページから開催日を調べる
  2. 開催日のページからrace_idを調べる
  3. race_idに対応したページからデータを抽出する

このページはステップ2に対応したコードです。全体像はこちら。

競馬 過去データcsvをnetkeibaから無料で入手する方法
JRA-VANを無料で使えるのはお試し期間のみ。競馬のデータ分析を継続して行うには、どうしても過去の競馬レース結果データを自前で収集する必要があります。netkeibaからのスクレイピング方法やデータをcsv 形式で保存する方法について記述しています。

スクレイピングを始める前に

Rでスクレイピングをするならrvestパッケージを使うのが簡単です。また、スクレイピングをするためにはHTML/CSSの理解も必要。とりあえず、これだけ知っていればスクレイピングは始められます。

Rでスクレイピングするならrvest 表もリンクもテキストも
Rでスクレイピングをするならrvestパッケージを使うのがベスト。表データ、リンク先URL、テキストなどのデータを簡単に入手できます。netkeibaのレース結果を題材にrvestパッケージの使い方をまとめています。
スクレイピングに必要な最低限のHTML/CSSの知識
スクレイピングでデータを収集するためには、HTMLで書かれたWebページの文書構造を理解し、どこに目的のデータが記載されているかをコンピュータに教えてやる必要があります。このページではスクレイピングに最低限必要なHTML/CSSの知識をまとめています。

Step2のコード

以下のコードでは、step1で抽出された開催日データ(race_dates.2012to2021.rdsに保存されている)をもとにrace_idを取得しています。

library(rvest)
library(stringr)
library(RSelenium)
library(tidyverse)

# レースIDを調べる
get_race_ids <- function(race_date){
    #netkeiba開催日のページへ移動する
    url<-paste0("https://race.netkeiba.com/top/race_list.html?kaisai_date=", race_date)
    rsChr$navigate(url)
    Sys.sleep(1)

    rtr<-rsChr$findElements(using="id", "RaceTopRace")
    Sys.sleep(1)

    if(length(rtr) !=0){
        pgsource<-rsChr$getPageSource()
        Sys.sleep(1)

        race_ids<- read_html(pgsource[[1]]) %>%
            html_nodes("#RaceTopRace > div > dl > dd > ul > li") %>%
            html_nodes("a") %>%
            html_attr("href") %>%
            str_split("=") %>%sapply(FUN=function(x){"[["(x,2)}) %>%
            str_split("&")%>%sapply(FUN=function(x){"[["(x,1)}) %>%
            unique()

        Sys.sleep(1)

    }else{
        race_ids<-NA
    }

    return (race_ids)
}

###################################################################
# 前処理
###################################################################

# selenium.jarの起動
system("java -jar selenium.jar &")

# Google Chrome 起動
rsChr <- RSelenium::remoteDriver(port = 4444L, browserName = "chrome")

# Webブラウザを開く
rsChr$open()

###################################################################
# スクレイピング
###################################################################

# 競馬開催日の読み込み
race_dates <- readRDS("race_dates.2022.1to2.rds")

#開催日(race_date)のレースのrace_idを取得する
length(race_dates)

res <- list()

#############

tmpfile <- "tmp.rds"
# res <- readRDS("tmpfile")

delta <- 500
(iend <- min((length(res) + delta), length(race_dates)))

system.time({
    for(iin (length(res) +1) :iend){
        cat(paste0("i =", i, "/" , iend, "\n"))

        race_date<-race_dates[i]
        cat(race_date)
        cat("\n")

        res[i] <-list(get_race_ids(race_date))

        cat("saveRDS\n")
        saveRDS(res, file=tmpfile)
        cat("Done\n\n")
    }
})

res
(res <- readRDS(tmpfile))

race_ids <- unlist(res)
any(is.na(race_ids))
which(is.na(race_ids))

saveRDS(race_ids, file = "race_ids.2022.1to2.rds")
(race_ids <- readRDS("race_ids.2022.1to2.rds"))

###################################################################
# 終了処理
###################################################################

# ブラウザを閉じる
rsChr$close()

#selenium.jarの終了。

#まず、selenium.jarのpidを確認
system("ps -A | grep 'java'")

# 6721 ?? 0:01.37 /usr/bin/java -jar selenium.jar
# 6724 ?? 0:00.01 sh -c ps -A | grep 'java'
# 6726 ?? 0:00.00 grep java
#
# pidをkillする(上の場合6721)

system("kill 58939") # selenium.jarをkillする

# killできていることの確認
system("ps -A | grep 'java'")
get_race_ids()関数について

上記のget_race_ids()はRSeleniumを使用してスクレイピングしていました。RSeleniumを使わない方法で同等の機能を持つget_race_ids()関数をつくりました。こちらの方が速いと思います。

競馬予想AIの作り方 〜 Rで出馬表をWebスクレイピング
前回の記事でせっかくスピード指数をスクレイピングしてデータベースを作ったのだから、次のレースの検討に活かしたい‼️そうすれば、きっと…(笑)。というわけで、今週末開催されるレースの出走テーブルをnetkeibaさんからスクレイピングさせてもらうことにしました。

step1に戻る場合はこちら

Rで競馬データをスクレイピング :step1コード
netkeibaのサイトから競馬開催日をスクレイピングするためのコードです。

step3に進む場合はこちら

Rで競馬データをスクレイピング :step3コード
race_idに対応したレース条件、レース結果、払い戻し情報をスクレイピングするためのコードです。