ログインが必要なページとかもざくざく掘ってみよう
以前の記事で基本的なRseleniumの使い方を書いたのですが:
https://qiita.com/taiyodayo/items/def80bc3503766b24a89
ログインが必要なサイトやインタラクティブなページからデータを抜くのに苦労されてる方が多いようで、
僕がやったことをまとめてみました。
Rvest使うと、html/cssの知識とかそんなに無くてもサクサク行けますよ。
開発は二通りのやり方がある:
・selenium-web-driverを起動したマシンでリアルタイムに要素名見ながらやる
・remDr$screenshot(display=TRUE) を見ながらチクチクやる
自分は後者が案外快適でした。
docker上で動くRStudioでちくちくインタラクティブに作っていきました。
「スクショ見る -> htmlファイルに落とす -> Chromeで開く -> xpath取ってコマンド書く」を繰り返すやり方です。
「スクショ取る」「今のページをhtmlに落として保存する」は頻繁にやるのでこれ用に関数書いた:
docker上で動くRStudioでちくちくインタラクティブに作っていきました。
# 開発・デバッグ用
remss <- function(){
remDr$screenshot(display=TRUE)
}
remhtml <- function(){
filename <- paste0("page_", today(), ".html")
write(unlist(remDr$getPageSource()), paste0("debug_", ymd_hms(now(tz="Asia/Tokyo")), ".html"))
}
中身は、殆どが下記の繰り返しです
・remDr$findElement で要素拾う (xpathで指定)
・webElem$sendKeysToElement で必要であれば要素代入
・webElem$clickElement() クリックイベントを送信
実際の所を御覧下さい:ログイン作業
# 某サイトにログインする関数
sitelogin <- function(){
# ログイン画面
url <- "https://www.hoge.hoge/zzh/"
remDr$navigate(url)
## Login - Page 1
# userid
webElem <- remDr$findElement(using="xpath", value = '//*[@id="searchBlock"]/div/div/div/div[1]/ul/li[1]/label/input')
webElem$sendKeysToElement(list("XXXUSERIDXXX"))
# password
webElem <- remDr$findElement(using="xpath", value = '//*[@id="searchBlock"]/div/div/div/div[1]/ul/li[2]/label/input')
webElem$sendKeysToElement(list("XXXPASSWORDXXX"))
# panel - fakepassword - 偽装パラメタを入れないとログイン蹴られる仕様
webElem <- remDr$findElement(using="xpath", value = '//*[@id="contentBody"]/form/input[1]')
webElem$sendKeysToElement(list("XXXX"))
# action
webElem <- remDr$findElement(using="xpath", value = '//*[@id="contentBody"]/form/input[2]')
webElem$sendKeysToElement(list("login"))
# Click login
webElem <- remDr$findElement(using="xpath", value = '//*[@id="searchBlock"]/div/div/div/div[2]/div/span')
webElem$clickElement()
message("STATUS - Login success.")
return(TRUE)
}
こんな感じです。
(実際にはエラーハンドリング等をもう少し手厚く書いています)
上記が動いたら、必要な商品IDなどを入れて狙ったデータを表示させられると思います。
必要な情報が表示されたら、そのページのhtmlをRvestでパース
はじめとっつきが悪いかもなんですが、基本こんな感じにtidyなパイプでどんどん処理できます。
殆どはhtml_table()とhtml_text()で取得出来ると思います。
sales <- read_html(remDr$getPageSource()[[1]]) %>%
html_node(xpath = '//*[@id="salesTrend"]/div[2]/table') %>%
html_table(fill = TRUE)
colnames(sales) <- c("stockdate","v_sold","v_souhin","v_soldcum","dummy","v_henpin","v_henpinratio")
sales %<>% select(-dummy) # remove junk col
sales %<>% mutate_at(c("v_sold", "v_souhin", "v_soldcum"), as_integer)
status_check <- read_html(remDr$getPageSource()[[1]]) %>%
html_node(xpath = '//*[@id="errorMsg"]/span') %>%
html_text
saveRDS(sales, "todaysdata.RDS")
あんがい簡単です。
取得時にfactorにしたり色々出来るので、.CSVにしてアホみたいに容量が膨らむ事も防げます。後処理に回しやすい。
すごいぞ便利だRvest
「スクレーピングとか、データサイエンスと離れた所は誰かにやって欲しい...」と感じる方も多いかと思うんですが、
Rvest + RSeleniumだと本当に簡単に自動化出来るんで、いっそ自分で書いちゃうのもありだと思って頂けたら幸いです。
取得データを、そのままRで触りやすい形で保存できるので便利ですよ〜
(取得は適切にsys.sleep()を挟むなどして、相手サイトさんの負担が多すぎないように実行しましょうね)
続きは本家サイトをチェックや