R) 크롤링 - 셀레늄 문제해결

R) 크롤링 - 셀레늄 문제해결

R에서 크롤링을 위해 Selenium(셀레늄)을 사용할 때 겪게 되는 여러가지 문제의 해결방법을 알아본다.


개요

R에서 Selenium(셀레늄)을 사용하여 크롤링을 하는 경우 보통 크롬 브라우저(Chrome Browser)를 사용하여 실시한다. 그런데 크롬 브라우저를 사용하는 경우 크롬 버전, 셀레늄 버전, 크롬 드라이버 버전 등의 버전이 서로 맞지 않으면 여러 문제가 발생하게 된다. 버전 외에도 다양한 문제가 있는데 이러한 문제들을 해결하는 방법을 알아본다.

문제 상황

JAVA

셀레늄을 사용하기 위해서는 JAVA가 설치되어 있어야 한다. JAVA는 다른 프로그램을 설치하거나 패키지를 운용하면서 나도 모르는 사이에 설치가 되어있는 경우가 많은데 그렇지 않은 경우도 있다. 그래서 JAVA가 설치되어 있지 않거나 환경변수가 제대로 등록되어있지 않은 경우 다음과 같은 에러가 발생한다.

Error in java_check() :
PATH to JAVA not found. Please check JAVA is installed.

포트(port)

셀레늄을 구동하기 위해서는 1개의 유휴 포트가 필요하다. 포트는 쉽게 말하면 컴퓨터간 통신하기 위한 통로라고 생각해도 되고 세상 밖으로 나가는 문의 번호라고 생각해도 되겠다. 아무튼 특정 프로그램은 이 포트 번호를 하나 점유하고 있을 수 있는데 이 때문에 셀레늄을 구동할 수 없는 경우가 있다.

셀레늄은 보통 기본적으로 4444번 포트를 사용한다. 그런데 다른 프로그램이 해당 포트를 점유하고 있거나 기존에 실행한 셀레늄 프로세스가 제대로 종료되지 않아 4444번 포트를 점유하고 있다면 다시 셀레늄을 구동할 때 에러가 발생한다.

버전(version)

다른 브라우저도 업데이트를 하긴 하지만 이 크롬 브라우저는 업데이트 속도가 엄청 빠르다. 단순히 브라우저를 사용하는 경우라면 업데이트는 언제나 환영이겠지만 셀레늄을 사용해서 크롤링을 하는 경우에는 크롬 브라우저와 크롬 드라이버의 버전이 맞아야 셀레늄 기반의 크롬 웹브라우저를 띄울 수 있기 때문에 서로 버전이 맞지 않게 되면 영 좋지 않다.

최근들어 업데이트 속도가 더욱 빨라져 자동으로 업데이트 되는 크롬 브라우저의 버전에 맞는 크롬 드라이버를 구하기 위해서는 공식 안정(stable)버전이 아닌 별도의 베타버전을 사용해야 하는 지경에 이르렀다.

기타

정말 드문경우지만 wdman 라이브러리가 각 웹 브라우저의 드라이버를 업데이트 하는 상황에서 인터넷 연결이 불안전해서 제대로 설치가 되지 않은 경우에 또 제대로 실행이 되지 않는 문제가 발생하기도 한다. 이 경우에는 드라이버가 설치된 폴더로 이동해서 드라이버 관련 파일을 전부 제거하고 다시 셀레늄을 구동하면 된다.

참고로 드라이버가 설치된 폴더는 다음과 같다.
※ C:\Users\계정명\AppData\Local\binman
웹 드라이버 설치 경로

문제 해결

JAVA

installr 패키지의 경우 R과 관련된 여러가지 프로그램을 설치할 수 있도록 도와주는 패키지이다. 그 중에서 JAVA도 포함되어 있으며 install.java() 함수를 사용하면 JAVA를 설치할 수 있다. 그런데 제대로 설치가 되지 않는 문제가 있다. 환경변수까지 잘 등록되어야 올바르게 동작하는데 다음과 같이 제대로 되지 않는 것을 볼 수 있다.
환경변수 JAVA_HOME이 등록되지 않음

그리고 상기 결과를 위해 사용한 코드는 다음과 같다.

1
2
3
4
5
6
7
8
library("installr")
install.java()
## trying URL 'https://download.java.net/openjdk/jdk11/ri/openjdk-11+28_windows-x64_bin.zip'
## Content type 'application/zip' length 187396683 bytes (178.7 MB)
## downloaded 178.7 MB

Sys.getenv("JAVA_HOME")
## [1] "C:/java/jdk-11"

사실상 Sys.getenv("JAVA_HOME") 코드 실행 결과가 없더라도 셀레늄은 정상동작 하기도 한다. 즉, 해당 코드의 결과가 현재 어떻게 보이더라도 지금 당장은 중요한 사안이 아니라는 것이다.

그래서 다음의 공식 사이트에서 JAVA를 다운로드 받아 설치하는 것이 좋다.
(https://www.java.com/ko/download/manual.jsp)[https://www.java.com/ko/download/manual.jsp]

그리고 해당 사이트에서 Windows 64bit 기준 설치파일을 다운로드 받아 실행한 결과는 다음과 같다.
JAVA 설치 시작

해당 파일을 설치하니 “C:\Program Files\Java” 경로에 JAVA가 설치된 것을 다음과 같이 확인할 수 있다. (버전은 딱히 관계 없음)
JAVA 설치 확인

이대로는 바로 셀레늄을 사용할 수 없다. 그래서 이제 시스템 환경 변수를 편집하러 설정으로 가본다.

다음 절차는 Windows11 운영체제 기준이다.

시스템 환경 변수 설정을 위해 시스템의 설정(제어파)으로 이동해서 “환경 변수”를 검색한다. 그 결과로 “시스템 환경 변수 편집”과 “계정의 환경 변수 편집” 항목을 볼 수 있는데, 그 중 “시스템 환경 변수 편집”을 클릭한다.
JAVA 환경 변수 설정-01

“시스템 환경 변수 편집”은 다음과 같다. “시스템 속성”창 아래부분의 “환경 변수(N)” 버튼을 누르면 오른쪽의 “환경 변수” 창이 뜨는데 해당 창의 아래 “시스템 변수(S)”부분의 “새로 만들기(W)” 버튼을 눌러준다.
JAVA 환경 변수 설정-02

그리고 드디어 대망의(?) “JAVA_HOME” 환경 변수 등록을 다음과 같이 해준다.
JAVA_HOME 환경 변수 등록

이제 다음과 같이 “RSelenium” 구동을 시도해보면 정상적으로 동작하는 것을 볼 수 있다. 😮😮😮
RSelenium 최초 구동

상기 캡쳐에 사용된 코드는 다음과 같다.

1
2
3
4
5
library("RSelenium")

remDr = rsDriver(remoteServerAddr = "localhost",
browser = "chrome",
port = 4444L)

최초에 실행할 때에는 여러 브라우저의 버전에 맞는 드라이버를 다운로드 받기 때문에 수 분 정도 기다려야 한다. 그.런.데….

[1] “Connecting to remote server”

Could not open chrome browser.
Client error message:
Undefined error in httr call. httr output: Failed to connect to localhost port 4444 after 2243 ms: Connection refused
Check server log for further details.
Warning message:
In rsDriver(remoteServerAddr = "localhost", browser = "chrome", :
Could not determine server status.

하…. 진짜….
Tlqkf

일단 설치는 됐으니 포트로 넘어가자.

포트(port)

앞서 말했듯 포트는 이미 다른프로그램에 의해 점유되었을 수 있고 기존에 실행되었던 셀레늄에 의해 점유되었던 것이 올바르게 종료되지 않아 문제가 발생한 것일 수 있다.

만약 전자라면 “port 4444 already in use”와 같은 메시지가 나올 것이고,
만약 후자라면 RStudio 세션을 재시작해서 다시 시도해볼 수 있다.

아무튼 이 포트를 rsDriver() 함수나 remoteDriver()에 적절한 값을 할당해줘야 하는데 보통 1000에서 8000사이의 정수를 입력하고(꼭 이 범위가 아니어도 됨) 반드시 올바른 불가변의 정수가 입력되게 하기 위해서 “numeric literal”을 사용하는 것이 좋다. 즉, port = 4444L와 같이 L을 붙여주는 것이다.

하지만 RStudio를 재시작해도 같은 포트 문제가 발생하고, Windows를 재시작해도 같은 포트 문제가 발생한다면 이것은 포트 하나의 문제가 아닐 수 있다.

셀레늄을 구동하기 위해서 rsDriver() 함수나 remoteDriver()를 쓸 수 있는데 상기의 rsDriver()로 제대로 되지 않는 것을 확인했으니 remoteDriver()를 써볼 수 있을 것이다. 다음의 코드를 보자.

1
2
3
4
5
6
7
8
library("RSelenium")

port_num = 4444L
ch = wdman::chrome(port = port_num)
remDr = remoteDriver(remoteServerAddr = "localhost",
port = port_num,
browserName = "chrome")
remDr$open()

웹 드라이버 메니저(web driver manager) 패키지인 wdmanchrome() 함수로 크롬 브라우저를 선 구동시키고 remoteDriver() 함수로 본격 실행시키는 코드이다. 물론 해당 코드를 실행해서 잘 된다면 이 포스트는 여기서 끝났겠지만 그렇지 않다.

[1] “Connecting to remote server”

Selenium message:session not created: This version of ChromeDriver only supports Chrome version 114
Current browser version is 119.0.6045.125 with binary path C:\Program Files\Google~
(Driver info: chromedriver=114.0.5735.90 (386bc~),platform=Windows NT 10.0.22621 x86_64)

Error: Summary: SessionNotCreatedException
Detail: A new session could not be created.
Further Details: run errorDetails method

하…. 진짜….
Tlqkf

아무튼 요약해보자면 시스템에 설치된 크롬 브라우저는 119.0.6045.125 버전인데 크롬 드라이버의 버전은 114 버전이다. 그렇다… 이제 버전 문제를 해결하러 가보자.

버전(version)

크롬 브라우저의 매우 빠른 업데이트 속도로 인해 정식 크롬브라우저의 버전이 따라오지 못하는 상태이다. wdman 패키지가 셀레늄 구동시 각 웹 브라우저의 최신 버전의 드라이버를 확인하고 업데이트를 한 다음에 셀레늄을 구동시키지만 앞의 에러는 크롬 드라이버의 정식버전 중 114 버전이 가장 높기 때문에 버전차이가 많이 나서 이런 문제가 발생하는 것이다.

크롬 브라우저의 버전을 확인하는 방법은 [설정]에서 [Chrome 정보]를 클릭하면 다음과 같이 볼 수 있다.
크롬 브라우저 버전 확인

정말 이 캡쳐를 찍는 순간에도 업데이트를 하고있다는 것이 놀라울 따름이다.

그리고 Windows 운영체제 기준, Chrome 브라우저 설치경로를 기본으로 했을 경우 다음의 R코드로 버전을 확인할 수 있다.

1
2
3
4
5
6
7
8
9
library("dplyr")
system2(command = "wmic",
args = 'datafile where name="C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe" get Version /value',
stdout = TRUE,
stderr = TRUE) %>%
stringr::str_extract(pattern = "(?<=Version=)(\\d+\\.){3}\\d+") %>%
na.omit() %>%
as.character()
## [1] "119.0.6045.125"

그다음에 크롬 드라이버의 가용 버전은 binman 패키지를 활용한 다음의 R코드로 확인할 수 있다.

1
2
3
binman::list_versions("chromedriver")
## $win32
## [1] "113.0.5672.63" "114.0.5735.16" "114.0.5735.90"

아무튼 이 상황에서는 크롬 브라우저의 버전에 맞는 크롬 드라이버를 구해야 하는데 wdman 패키지에 의존할 수 없는 상황이고 직접 브라우저를 구하러 가야한다. 🤬

자 이제 크롬 드라이버의 테스트버전 페이지로 이동해보자.
https://googlechromelabs.github.io/chrome-for-testing/#stable
크롬 드라이버 테스트 버전 페이지

상기 페이지에서 본인의 운영체제에 맞는(본인은 win64에 해당하는 것을 받음) 웹 브라우저와 가장 가까운 버전의 파일을 받으면 되고 본인은 “119.0.6045.105”에 해당하는 크롬 드라이버를 받았다.
https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/119.0.6045.105/win64/chromedriver-win64.zip

향후 크롬 드라이버를 특정 폴더에서 관리하고자 하여 다음과 같이 폴더를 만들고 압축을 풀었다.
크롬 드라이버 테스트 버전 페이지

그리고 해당 폴더의 경로를 환경변수에 다음과 같이 등록하였다.
크롬 드라이버 위치 시스템 환경 변수 등록

그리고 시스템을 재부팅 한 후 셀레늄을 실행시키면 다음과 같이 정상 동작한다.
RSelenium 최초 정상 구동

상기 구동을 위해 작성한 코드는 다음과 같다. 참고로 이렇게 하면 새로운 웹드라이버를 다운로드 받지 않아 최초 구동 시간이 약간 단축된다.

1
2
3
4
5
6
7
8
9
library("RSelenium")

remDr = rsDriver(remoteServerAddr = "localhost",
browser = "chrome",
geckover = NULL,
iedrver = NULL,
chromever = NULL,
phantomver = NULL,
port = 4444L)

아무튼 끝났고 해냈다.
토심이 - 내가 해냄

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×