rvestで動的サイトをスクレイピングする(Seleniumを使わずに)

rvest
R
Japanese
公開

2024年2月15日

RにおけるWebスクレイピングのこれまで

RにおけるWebスクレイピングの定番パッケージにrvestがありますが,これまでブラウザ上の操作によってコンテンツが変化する動的サイトのスクレイピングにはrvestを用いることができませんでした.そのため,Rで動的サイトのスクレイピングには,RSeleniumなどの他のパッケージと組み合わせて利用する必要があり,以下のような課題が生じていました.

  • Seleniumを用いる場合には,事前にドライバをダウンロードする必要があるなど環境構築が面倒
  • 他のパッケージで取得したHTMLに対してrvestの関数をシームレスに適用できない

しかし,rvest 1.0.4では,read_html_live()という新たな関数が追加され,動的サイトのスクレイピングが可能となりました.read_html_live()を用いることで,$click()$type()などのメソッドを用いたブラウザ上の操作の自動化が可能となるだけでなく,html_elements()html_attr()などの一般的なrvestの関数をシームレスに呼ぶことができるようになります.

read_html_live()は,Google Chromeの自動化を行うchromoteというパッケージを利用しています.そのため,read_html_live()を使うには,事前にGoogle Chrome(ブラウザ)とchromote(Rパッケージ)をインストールしておく必要があります.

read_html_live()を使ってみよう

ここからは,こちらのRSeleniumのチュートリアルで紹介されているものと同じ処理をread_html_live()で行ってみましょう.

こちらのチュートリアルでは,こちらのサイトにアメリカの郵便番号(ZIP code)を入力して地元テレビ局の情報を取得するという一連の処理を自動化しています. read_html_live()を使えば,RSeleniumでのサイトのアクセスを以下のように書き換えられます.

# RSelenium
# Source: https://joshuamccrain.com/tutorials/web_scraping_R_selenium.html
library(RSelenium)

rD <- rsDriver(browser="firefox", port=4545L, verbose=F)
remDr <- rD[["client"]]
remDr$navigate("https://www.fcc.gov/media/engineering/dtvmaps")

# rvest
library(rvest)
library(tidyverse)

html <- read_html_live("https://www.fcc.gov/media/engineering/dtvmaps")

読み込まれたオブジェクトは,$view()でブラウザで確認することができます.サイト上のエレメントを選択(Ctrl+Shift+C)したのち,該当箇所を右クリック⏩CopyCopy selectorでCSSセレクタをコピーすれば,$type()$click()の引数として使うことができます.

# rvest
html$view()

次に,中央のフォームに郵便番号(ZIP code)を入力⏩Go!ボタンをクリックし地元テレビ局の情報を表示させるコードは以下のように書き換えられます.

# RSelenium
# Source: https://joshuamccrain.com/tutorials/web_scraping_R_selenium.html
zip <- "30308"
remDr$findElement(using = "id", value = "startpoint")$sendKeysToElement(list(zip))
remDr$findElements("id", "btnSub")[[1]]$clickElement()

# rvest
zip <- "30308"
html$type("#startpoint", zip)
html$click("#btnSub")

最後に,上記のRSeleniumのチュートリアルと同じデータが取得できたことを確認しましょう.

# rvest
html |> 
  html_elements("table.tbl_mapReception") |> 
  insistently(chuck)(3) |> 
  html_table() |> 
  select(!c(1, IA)) |> 
  rename_with(str_to_lower) |> 
  rename(ch_num = `ch#`) |> 
  slice_tail(n = -1) |> 
  filter(callsign != "")

まとめ

以上のようにrvest 1.0.4で追加されたread_html_live()を使うことで,rvestだけでシームレスに静的サイトと動的サイトのスクレイピングが可能となるだけでなく,RSeleniumと比べてシンプルなコードでブラウザ上の操作を再現することができることがわかりました.

Rには,rvestの他にもseleniderというWebスクレイピング用のパッケージも開発されているようです.こういったパッケージの開発が進むことで,RでのWebスクレイピングがさらに便利になることが期待されます.