셀레니움 봇 탐지 우회 - sellenium bos tamji uhoe

셀레니움을 사용하다보면 어떤 웹사이트에서는 작동이 되지 않거나, 혹은 봇이 탐지되었다고 거부를 당하는 일이 있다. 셀레니움 웹 크롤링 봇 탐지 우회하는 방법을 찾아 이곳까지 왔다면 정말 제대로 찾아왔다. 웹사이트마다 접속자 Bot이라고 인식하는 방법은 여러가지가 있기 때문에 웹사이트마다 봇으로 인식되어 거부당하는 것을 하나로 설명할 수 없다. 다만! 봇으로 인식되지 않게 하는 해결책은 이 글 하나로 90%를 커버할 수 있다. 궁금한 점이나 설명이 부족한 부분을 댓글로 지적해주면 해당 부분에 대한 설명을 보충하여 글이 업데이트 됩니다.


목차

  • 셀레니움 웹 크롤링 봇탐지 우회
  • 드라이버 구동
  • 디버거 크롬
  • 마치며


셀레니움 웹 크롤링 봇탐지 우회

크롬 셀레니움을 구동해보면 우리는 이런 창을 자주 보게 된다.

셀레니움 봇 탐지 우회 - sellenium bos tamji uhoe

Chrome이 자동화된 테스트 소프트웨어에 의해 제어되고 있습니다. 저것은 그냥 우리의 눈으로만 보이는 것이 아니라, 저러한 정보가 웹사이트 서버에 사용자 정보로 전달이 된다. 쉽게 말해 웹사이트는 접속자가 셀레니움을 사용해서 접속했다는 것을 쉽게 알 수 있다는 의미이고 셀레니움으로 접속을 한 경우 접속을 거절하도록 설정해둘 수 있다.

그럼 우리는 어떡해야하나? 간단하다. 일반 크롬과 똑같은 설정으로 셀레니움을 접속시키면 된다. 이를 보통 디버거 크롬이라고 부른다. 자! 이 글에서는 당장의 문제를 해결하도록 소스를 통으로 보여주고 쓸데없는 말은 전부 제거하여 쓸데없는 공부의 고통을 줄이도록 하겠다.

드라이버 구동

일단 기본적으로 드라이버를 구동하는 방법은 셀레니움 설치와 크롬 드라이버 자동 처리 를 참조한다. 이 소스를 통으로 복붙해서 쓰는 습관을 가지면 정말 코딩과 디버깅이 편리해진다.

위 글의 핵심 코드를 다시 써보자면 아래와 같다.

from selenium import webdriver
import chromedriver_autoinstaller

chrome_ver = chromedriver_autoinstaller.get_chrome_version().split('.')[0]  #크롬드라이버 버전 확인

try:
    driver = webdriver.Chrome(f'./{chrome_ver}/chromedriver.exe')   
except:
    chromedriver_autoinstaller.install(True)
    driver = webdriver.Chrome(f'./{chrome_ver}/chromedriver.exe')

driver.implicitly_wait(10)

위 코드를 실행하면 자동화된 테스트 소프트웨어에 의해 제어되고 있습니다 라는 멘트가 나타나게 되는데 코드를 조금 수정해서 디버거 크롬으로 구동하는 방법을 알아보자

디버거 크롬

거두절미하고 소스부터 갖다 붙이자면 아래와 같다. 내용을 먼저 이해하고 사용하기 보다는 일단 소스를 복붙해서 무작정 실행부터 해보는 것이 좋다고 생각한다.


from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import chromedriver_autoinstaller
import subprocess

subprocess.Popen(r'C:\Program Files\Google\Chrome\Application\chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\chrometemp"') # 디버거 크롬 구동


option = Options()
option.add_experimental_option("debuggerAddress", "127.0.0.1:9222")

chrome_ver = chromedriver_autoinstaller.get_chrome_version().split('.')[0]
try:
    driver = webdriver.Chrome(f'./{chrome_ver}/chromedriver.exe', options=option)
except:
    chromedriver_autoinstaller.install(True)
    driver = webdriver.Chrome(f'./{chrome_ver}/chromedriver.exe', options=option)
driver.implicitly_wait(10)

위 코드에 대해 설명을 하자면

subprocess.Popen 은 크롬 브라우저를 실행시키는 명령어이다. 일단 chrome.exe 파일이 내 컴퓨터 어디에 위치해 있는지 확인이 필요하다. 대부분의 컴퓨터는 아래 둘중의 한군데에 설치되어 있다.

C:\Program Files\Google\Chrome\Application\
C:\Program Files (x86)\Google\Chrome\Application\

두 경로 다 찾아보았는데 내 컴에는 없다면 크롬이 설치되어 있지 않거나 혹은 본인이 크롬을 설치할 때 다른 경로에 설치한 것이니 어디에 설치되어 있는지는 본인만이 알 수 있다. (참고로 윈도우 사용자를 기준으로 설명하였다.)

자 그럼 chrome.exe 파일을 실행시키되 명령어 뒤에 보면 옵션이 보인다. –remote-debugging-port=9222 는 구동하는 크롬의 포트를 알려주는 것이다. 포트가 무엇인지는 알필요 없다. 그냥 저 옵션을 넣어주면 된다고만 이해해도 충분하다. –user-data-dir=”C:\chrometemp” 는 크롬을 사용하여 웹상을 돌아다녔을 때 생기는 쿠키와 캐쉬파일을 저장하는 곳이다.

일반 셀레니움은 쿠키와 캐쉬파일을 저장하지 않는다. 저장할 필요가 없기 때문이다. 따라서 셀레니움 드라이버를 구동할때마다 쿠키와 캐쉬가 완전히 삭제된 새로운 브라우저창이 열린다. 그러나 우리가 지금 사용하려는 디버거 크롬은 일반 크롬과 동일하기 때문에 쿠키와 캐쉬를 저장한다. 만약 디버거 크롬을 사용할 때마다 자동으로 쿠키와 캐쉬파일을 삭제하도록 처리하고 싶다면 C:\chrometemp 폴더 이하 파일들을 삭제해주면 된다.

코드로 처리하자면 아래와 같이 하면 되겠다.

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import chromedriver_autoinstaller
import subprocess
import shutil

try:
    shutil.rmtree(r"c:\chrometemp")  #쿠키 / 캐쉬파일 삭제
except FileNotFoundError:
    pass

subprocess.Popen(r'C:\Program Files\Google\Chrome\Application\chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\chrometemp"') # 디버거 크롬 구동


option = Options()
option.add_experimental_option("debuggerAddress", "127.0.0.1:9222")

chrome_ver = chromedriver_autoinstaller.get_chrome_version().split('.')[0]
try:
    driver = webdriver.Chrome(f'./{chrome_ver}/chromedriver.exe', options=option)
except:
    chromedriver_autoinstaller.install(True)
    driver = webdriver.Chrome(f'./{chrome_ver}/chromedriver.exe', options=option)
driver.implicitly_wait(10)

실행 원리에 관한 보다 자세한 정보를 알고 싶다면 열려있는 chrome에서 크롤링하기 를 참조하면 좋다. 좋은 정보를 제공해주신 작성자님께 감사의 말씀 전합니다.

마치며

위 코드로 실행하면 거의 대부분의 봇탐지를 우회할 수 있다. 브라우저 설정이 일반 크롬과 동일하기 때문이다. 그럼에도 불구하고 봇탐지 걸리는 경우가 있다. 예를 들자면 네이버/구글 로그인이 그렇다. 웹사이트에서 접속자가 사람이 아닌 봇으로 인지하는 경우는 크게 두가지이다. 하나는 위와같은 브라우저 설정을 보는 것이고 하나는 웹페이지에서 자바스크립트가 실행되었는지로 따지는 것이다.

우리는 보통 셀레니움으로 엘리먼트를 찾아서 클릭하고 텍스트등을 적고 전송한다. 거의 대부분의 작업이 클릭, 스트링전송, 텍스트 읽어보기 등일 것이다. 셀레니움에서 이러한 작업은 우리가 보통 element.click() / element.send_keys(‘~~~’) 와 같은 메소드등을 사용하는데 이 메소드가 바로 자바스크립트를 사용해서 웹페이지상에 버튼을 클릭하거나 스트링을 넣을 수 있도록 하는 것이다. 일반인 사용자는 웹페이지에서 직접 키보드로 타이핑을 하거나 마우스를 클릭하지 자바스크립트로 무언가를 실행하지 않는다.

어느 정도 감이 왔는가? 결국 위 함수를 사용하지 않고 웹페이지를 사용하도록 하는 것이다. 매크로를 이용하던 (autohotkey 추천) 다른 방법을 사용해도 좋다. 자바스크립트가 실행되지 않고 스트링을 입력하더나 무언가를 클릭하게 하면 된다.

후자에 관한 부분은 나중에 따로 포스팅하도록 하겠다.

셀레니움 웹 크롤링 봇 탐지 우회 2탄 네이버 로그인 캡차 피하기

궁금한점이나 설명이 부족한 부분을 지적해주면 해당 부분의 설명을 보강하여 글을 업데이트 됩니다.

2021.3.5. updated

2021.4.3. updated