본문 바로가기

Python 업무 자동화

구글·네이버 봇 차단을 무력화하는 셀레늄 3대 우회 보안 설정 노하우

구글·네이버 봇 차단을 무력화하는 셀레늄 3대 우회 보안 설정 노하우

자동 포스팅 모듈을 만들고 "이제 손가락 하나 까딱 안 해도 매일 글이 올라가겠구나!"라며 기뻐했던 것도 잠시였습니다. 며칠간 정상적으로 작동하던 자동 포스팅 스크립트가 어느 날 갑자기 먹통이 되었습니다. 구글 로그인 화면에는 '안전하지 않은 브라우저'라는 경고가 떴고, 네이버나 티스토리에 접속할 때는 '로봇이 아닙니다'라는 캡차(CAPTCHA) 장벽에 가로막혔습니다.

포털 사이트의 보안 엔진이 제 파이썬 셀레늄(Selenium) 스크립트를 '자동화 봇'으로 감지하고 차단한 것입니다.

이 장벽을 극복하지 못하면 아무리 훌륭한 자동화 코드를 짜 두어도 무용지물이 됩니다. 웹사이트들이 자동화 봇을 감지하는 메커니즘을 역으로 추적해 보니, 웹 브라우저가 남기는 몇 가지 치명적인 '봇의 흔적' 때문이었습니다. 이번 글에서는 구글, 네이버, 티스토리 등의 보안 방화벽을 우회하여 사람처럼 브라우저를 작동시키는 셀레늄 3대 핵심 우회 설정 노하우를 공유해 드립니다.

구글과 네이버의 보안 봇 차단 필터에 가로막혀 곤혹스러워하는 모습 (AI 분위기 이미지 - 파일명: image_01.png)

1. navigator.webdriver 플래그 무력화 (가장 치명적인 흔적 제거)

웹사이트의 방화벽이 셀레늄 봇을 감지하는 가장 첫 번째 기준은 브라우저의 내장 자바스크립트 객체인 navigator.webdriver 값입니다.

일반 사용자가 크롬을 켜서 사이트에 접속하면 이 값은 undefined 또는 false로 나옵니다. 하지만 셀레늄 드라이버가 크롬을 제어하여 구동시키면 이 값이 강제로 true로 세팅됩니다. 보안 엔진들은 자바스크립트 한 줄(console.log(navigator.webdriver))로 이 값이 true인 접속자를 판별해 즉시 캡차를 띄우거나 로그인을 막아버립니다.

이 흔적을 지우기 위해서는 크롬이 실행될 때 봇 제어 기능이 활성화되었다는 내부 정보(Blink Features)를 강제로 꺼 주어야 합니다. 파이썬 코드에 아래 설정을 반드시 주입해야 합니다.

options = webdriver.ChromeOptions()
# 봇 감지 방지용 핵심 인자 주입
options.add_argument('--disable-blink-features=AutomationControlled')
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)

이 옵션을 넣고 크롬을 켜면 웹사이트의 보안 자바스크립트가 브라우저의 navigator.webdriver 값을 조회해도 false로 인식하게 되어 첫 번째 탐지 필터를 가뿐히 통과할 수 있습니다.

VS Code 에디터 창에서 봇 감지 우회 코드를 신중하게 작성하고 튜닝하는 모습 (AI 분위기 이미지 - 파일명: image_02.png)

2. 유저 에이전트(User-Agent) 변장술

두 번째로 보안 솔루션이 검사하는 정보는 브라우저의 신분증에 해당하는 유저 에이전트(User-Agent) 문자열입니다.

셀레늄을 통해 헤드리스(Headless, 브라우저 창을 띄우지 않는 백그라운드 모드) 모드로 크롬을 실행하면, 유저 에이전트 값에 HeadlessChrome이라는 단어가 선명하게 찍혀서 전송됩니다. 서버 입장에서는 "나는 자동화 봇입니다"라고 광고하는 접속자를 굳이 들여보낼 이유가 없습니다.

따라서 헤드리스 모드를 쓸 때뿐만 아니라 일반 모드에서도 유저 에이전트 값을 실제 사람이 쓰는 최신 윈도우 크롬 브라우저 정보로 덮어씌워 변장해야 합니다.

# 실제 윈도우 11 크롬 브라우저의 User-Agent 정보로 위장
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
options.add_argument(f'user-agent={user_agent}')

이렇게 하면 서버 측 보안 로그에는 기계가 아닌 평범한 윈도우 PC 사용자가 크롬 브라우저로 직접 접속한 것으로 기록됩니다.

실제 작동 로그 상에서 자동화 봇 식별자가 인간 접속자로 완벽히 위장되어 서버를 통과하는 모식도 (일러스트 이미지 - 파일명: image_03.png)

3. 인간적인 딜레이와 랜덤 시간 가드

세 번째 보안 감지 기준은 동작의 규칙성입니다.

인간은 마우스를 움직이고 클릭하고 페이지를 이동할 때 1.2초, 3.4초, 0.8초 등 매번 다른 시간 간격을 둡니다. 반면 투박하게 작성된 파이썬 매크로는 글쓰기 버튼 클릭 후 정확히 2.000초 뒤에 다음 버튼을 누릅니다. 초 단위 이하의 규칙적인 패턴이 반복되면 보안 엔진은 즉시 시스템 차단 알고리즘을 발동합니다.

이를 회피하기 위해 모든 time.sleep() 구간에 수학적 무작위성(Randomness)을 부여해야 합니다.

import time
import random

# 고정된 time.sleep(2) 대신 무작위 대기 시간 주입
def human_delay(min_sec=1.0, max_sec=3.0):
    delay = random.uniform(min_sec, max_sec)
    time.sleep(delay)

# 포스팅 동작 사이에 인간적인 호흡을 부여
driver.find_element(By.XPATH, '...').click()
human_delay(1.5, 3.5) # 1.5초에서 3.5초 사이의 랜덤한 시간 동안 대기

동작과 동작 사이에 사람이 생각하고 행동하는 것 같은 엇박자 딜레이를 살짝 얹어주면, 서버의 행동 패턴 분석 감지기(Behavioral Analytics)를 아주 손쉽게 우회할 수 있습니다.

우회 옵션과 랜덤 딜레이가 장착된 자동화 브라우저가 보안 검문을 통과해 글쓰기에 성공하는 화면 (웹 UI 시뮬레이션 화면 - 파일명: image_04.png)

결론: 지속 가능한 자동화를 위한 필수 가드

셀레늄으로 웹을 자동화할 때 보안 솔루션을 우회하는 것은 단순히 해킹이나 꼼수의 영역이 아닙니다. 포털 사이트가 악성 도배 스팸을 막기 위해 쳐둔 그물망에, 우리처럼 건전한 자동 업로드 생산성 봇이 억울하게 걸려들지 않도록 브라우저의 옷을 제대로 입혀주는 방어 코딩입니다.

오늘 소개해 드린 세 가지 우회 설정(navigator.webdriver 제거, User-Agent 위장, 랜덤 딜레이)만 코드 뼈대에 기본 장착해 두어도, 캡차 블락이나 로그인 오류 없이 365일 내내 무인으로 돌아가는 단단한 자동 발행 파이프라인을 유지할 수 있습니다.

다음 글에서는 크롬 드라이버 버전이 올라갈 때마다 수동으로 다운로드받는 귀찮은 일 없이, 자동으로 버전을 체크하고 연동해 주는 '웹드라이버 매니저(WebDriver Manager)' 모듈의 자동 갱신 팁에 대해 상세히 알아보겠습니다.