RSelenium을 사용하여 로그인에 captcha 인증이 필요한 페이지 스크래핑

13684 단어 R셀레늄scraping
Project Euler의 Statistics 페이지( Statistics - Project Euler )에서 사용 언어별 통계 정보를 얻는 것을 목표로 한다. 이 페이지는 로그인하지 않으면 열람할 수 없고, 로그인에는 화상 인증이 필요하다. 이번에 이미지 인증을 (반 수동으로) 돌파하기 위해 RSelenium 패키지를 사용한다.

준비



Selenium Server 시작



우선, 어떠한 방법으로 Selenium Server를 기동해 둘 필요가 있다. 현재, RSelenium의 Vignette( RSelenium: Basics )에서는 Docker 컨테이너의 이용이 추천되고 있어 Docker를 사용하는 경우를 위한 vignett도 별도 준비되어 있다( RSelenium: Docker ).

이번은 추천의 순서에 따라 Selenium을 도입해, 로컬로 Selenium Serever가 기동되고 있다고 한다.

터미널
% docker run -d -p 4445:4444 selenium/standalone-firefox

사용할 패키지



아래의 패키지를 이용한다.
# install.packages("RSelenium", "rvest") # インストールしていなければインストール
library(RSelenium)
library(rvest)
rvest는 이번에 취득한 html의 취급에 사용했다. 자료 취득 자체는 RSelenium에서 갔다.

스크래핑



웹 사이트에 연결



우선, remoteDriver 클래스의 인스턴스를 작성한다. 이 때 Selenium Server 시작시 지정한 정보를 입력합니다.
remDr <- remoteDriver(remoteServerAddr = "localhost",
                      port = 4445L,
                      browserName = "firefox")

서버에의 접속은 open 메소드를 이용한다.
remDr$open()

성공적으로 연결되어 있으면 getStatus() 메서드에서 상태를 얻을 수 있어야합니다.
> remDr$getStatus()
$ready
[1] TRUE

(...以下略)

또한 screenshot() 메소드를 사용하면 현재 화면의 스크린 샷을 얻을 수 있습니다. display=TRUE를 지정하면 RStudio라면 Viewer 창에서 내용을 확인할 수 있으므로 현재 상황을 확인하고 싶으면 적절하게 실행하면 된다. 또, 이번 captcha의 확인에도 사용한다.

스크린샷을 뷰어 창에 표시
remDr$maxWindowSize()
remDr$screenshot(display=TRUE)

로그인 정보 입력



양식에 대한 정보 입력은 webElement 클래스의 sendKeysToElement 메소드를 사용한다.
## usernameとpassword入力
webElem <- remDr$findElement(using="id", value = "username")
webElem$sendKeysToElement(list("your_username")) # 自身のユーザー名に置き換える
webElem <- remDr$findElement(using="id", value = "password")
webElem$sendKeysToElement(list("your_password")) # 自身のパスワードに置き換える

captcha 부분은 보지 않으면 모르기 때문에, 보고 입력한다. screenshot 를 사용하자.
## captcha情報確認のためスクリーンショットをとる
remDr$maxWindowSize()
remDr$screenshot(display=TRUE)

## captcha入力
webElem <- remDr$findElement(using="name", value = "captcha")
webElem$sendKeysToElement(list(readline("confirmation code: "))) # 確認した値を入力

정보를 입력한 후 로그인하세요.
## サインインボタンクリック
webElem <- remDr$findElement(using="name", value = "sign_in")
webElem$clickElement()

데이터 검색


getPageSource 메소드로 html을 얻을 수 있으므로, 나중에는 rvest 를 사용하면 됩니다.
## 目的のページへ移動
remDr$navigate("https://projecteuler.net/languages")

## rvestでテーブル取得
df <- remDr$getPageSource()[[1]] %>% read_html %>% html_table %>% `[[`(1)



모처럼이므로 plot 해 보았다.
library(ggplot2)

plotdf <- function(target){
  df %>%
    filter(rank(eval(target)) > nrow(df)/2) %>%
    ggplot(aes(x = reorder(Language, eval(target)), y = eval(target))) +
    geom_col() +
    coord_flip() +
    xlab("Language") +
    ylab(target) +
    theme_classic()
}

plotdf(quote(`Total Number of Members`))
plotdf(quote(`Mean Percentage of Problems Solved`))

언어별 순위. Project Euler는 속도를 요구할 수 없기 때문에, R에서도 충분히 싸울 수 있다.



해답률로 정렬하면 양상이 일변하고 재미있다. 유저수가 10명에 못 미치는 듯한 언어가 많이 들어온다(그러니까 상위에 들어가기 쉬운, 라고 하는 견해도 할 수 있을 것이다). 톱 Stata는 현시점에서 유저수 16명이다.



참고


  • rvest로 로그인하여 스크래핑 #rstatsj - Qiita
  • [번역] RSelenium vignette: RSelenium의 기본 - Qiita
  • RSelenium: Basics
  • RSelenium: Docker
  • 좋은 웹페이지 즐겨찾기