브라우저 자동화 차단 방지: 4계층 방어 스택 — Clawbrowser 블로그 커버 이미지

브라우저 자동화 차단 방지: 4계층 방어 스택 완벽 가이드

Clawbrowser Team브라우저-자동화안티봇핑거프린팅가이드

로컬에서 잘 돌아가던 자동화 스크립트를 서버에 배포하면 몇 시간 만에 403, CAPTCHA, 혹은 빈 HTML만 반환되는 상황을 겪어보셨을 겁니다. 코드는 동일한데 왜 갑자기 차단되는 걸까요? 차이는 브라우저가 실행되는 환경에 있습니다. anti-bot 시스템은 그 환경을 네 가지 계층에 걸쳐 읽어내기 때문입니다.

요약: 브라우저 자동화가 차단되는 이유는 anti-bot 시스템이 네 가지 계층을 동시에 확인하기 때문입니다. 브라우저 identity(fingerprint), 네트워크 신호(IP, TLS), 행동 패턴(마우스, 타이밍), 세션 관리(쿠키, 상태). 한 계층만 수정하면 나머지 세 계층이 열린 상태로 남습니다. 근본적인 해결은 아래에서 위로: 먼저 브라우저 엔진 레벨에서 일관된 fingerprint와 proxy 라우팅을 확보한 뒤, 행동과 세션은 코드로 처리하는 것입니다.


자동화가 차단되는 근본 원인

Cloudflare, Akamai, PerimeterX, DataDome 같은 anti-bot 시스템은 단일 검사에 의존하지 않습니다. 여러 신호를 동시에 점수화합니다. IP가 깨끗해도 navigator.webdriver 플래그가 노출되면 차단됩니다. fingerprint가 완벽해도 데이터센터 IP에서 요청하면 차단됩니다. 탐지가 계층 구조이므로 방어도 계층 구조여야 합니다.

네 가지 계층을 가장 기본적인 것부터 정리하면 다음과 같습니다.

계층 검사 대상 수정 위치
1. 브라우저 identity fingerprint, 자동화 플래그, 엔진 신호 브라우저 바이너리
2. 네트워크 IP 평판, TLS fingerprint, DNS, WebRTC proxy 설정
3. 행동 패턴 마우스 이동, 타이밍, 스크롤 패턴 애플리케이션 코드
4. 세션 관리 쿠키, 로그인 상태, 요청 빈도 애플리케이션 코드

1-2 계층은 인프라 문제이고, 3-4 계층은 코드 문제입니다. 대부분의 개발자가 3계층(랜덤 딜레이 추가)부터 시작하는데, 그 사이 1-2 계층은 완전히 열려 있습니다. 수정이 지속되지 않는 이유가 여기에 있습니다.

1계층: 브라우저 identity

대부분의 자동화가 실패하는 지점이면서, 대부분의 개발자가 확인하지 않는 지점이기도 합니다.

Playwright나 Puppeteer로 제어하는 기본 Chromium 인스턴스는 20개 이상의 표면에서 자동화 신호를 노출합니다. navigator.webdriver가 true로 설정되어 있고, chrome.runtime 객체가 누락되며, WebGL 렌더러 문자열이 headless GPU 드라이버를 드러내고, Canvas readback은 결정론적 해시를 생성하며, AudioContext 출력이 실제 하드웨어와 일치하지 않습니다. anti-bot 스크립트는 페이지 로드 후 200ms 안에 이 모든 것을 수집합니다. 여러분의 코드가 실행되기도 전입니다.

효과 없는 접근법

stealth 플러그인 (puppeteer-extra-plugin-stealth, playwright-stealth 등)은 일부 신호를 페이지 레벨에서 패치합니다. JavaScript로 navigator.webdriver를 오버라이드하는 방식입니다. 문제는 anti-bot 시스템이 페이지가 아니라 브라우저 엔진 자체에서 신호를 읽는다는 점입니다. JavaScript로 navigator.webdriver를 오버라이드하면 property descriptor가 실제 브라우저와 달라져서 탐지됩니다. Canvas와 WebGL readback은 GPU 파이프라인에서 나오므로 JavaScript로는 손댈 수 없습니다. 페이지 레벨 패치로는 엔진에 도달할 수 없습니다.

랜덤 User-Agent 문자열은 20개 이상의 신호 중 하나만 변경합니다. User-Agent는 macOS라고 하는데 WebGL 렌더러는 Linux GPU 드라이버를 보고하고, 글꼴은 Windows 전용이며, timezone offset이 locale과 맞지 않으면 — spoofing하지 않은 것보다 더 심한 불일치를 만들어냅니다.

headless 모드 (--headless)는 headed Chrome과 완전히 다른 fingerprint를 생성합니다. 화면 해상도, GPU 렌더링 경로, 글꼴 렌더링, 플러그인 목록이 전부 다릅니다. 일부 사이트는 headless를 아예 차단합니다.

실제로 효과 있는 방법

해결은 브라우저 바이너리 레벨에서 이루어져야 합니다. anti-detect browser는 Chromium 엔진 내부에서 fingerprint 신호를 패치하여 20개 이상의 모든 표면에서 일관성을 확보합니다. Canvas, WebGL, AudioContext, 글꼴, navigator 속성, client rects, media devices, 화면 해상도, timezone, 언어, WebRTC — 모두 하나의 실제 디바이스 프로필에 맞는 값을 보고합니다.

핵심 키워드는 일관성입니다. 개별 신호를 spoofing하면 모순이 생깁니다. 관리된 fingerprint는 모든 신호가 같은 이야기를 하도록 보장합니다.

20개 이상의 신호에 대한 상세 분석은 브라우저 지문 설명: anti-bot 시스템이 자동화를 감지하는 20개 이상의 신호를 참고하세요.


2계층: 네트워크

브라우저 identity가 완벽해도 플래깅된 IP에서 요청하면 차단됩니다. anti-bot 시스템은 네트워크 계층을 독립적으로 검사합니다.

IP 평판

데이터센터 IP(AWS, GCP, Azure, DigitalOcean)는 이미 목록화되어 있습니다. anti-bot 업체들은 클라우드 인프라와 연관된 IP 대역 데이터베이스를 유지합니다. 이 대역에서 오는 요청은 브라우저 fingerprint와 무관하게 더 높은 검증을 받거나 즉시 차단됩니다.

실제 ISP의 residential IP는 차단율이 훨씬 낮습니다. 수치로 보면 동일한 자동화 스크립트, 동일한 브라우저 identity로 데이터센터 IP에서 90% 차단율이던 것이 residential proxy를 쓰면 5% 미만으로 떨어지는 경우도 있습니다.

TLS fingerprint

모든 HTTPS 연결은 TLS 핸드셰이크로 시작됩니다. ClientHello 메시지의 cipher suite 순서, 확장 기능, 지원 곡선 조합이 TLS fingerprint(JA3/JA4)를 만듭니다. 기본 Chromium, headless Chrome, Playwright는 각각 다른 JA3 해시를 생성합니다. TLS fingerprint가 "자동화 도구"라고 말하는데 User-Agent는 "Chrome 126 on macOS"라고 하면 세션이 플래깅됩니다.

해결: 실제 Chrome TLS fingerprint를 생성하는 브라우저 바이너리를 사용해야 합니다. 페이지 레벨 proxy나 HTTP 라이브러리로는 TLS fingerprint를 수정할 수 없습니다. 핸드셰이크는 JavaScript가 실행되기 전에 일어나기 때문입니다.

지리적 정합성

브라우저 fingerprint가 미국 영어 locale, 미국 timezone을 보고하는데 IP가 프랑크푸르트의 데이터센터로 지오로케이션되면 anti-bot 시스템이 불일치를 감지합니다. proxy 라우팅은 지리적으로 정합해야 합니다. IP 위치가 fingerprint의 timezone, 언어, locale과 일치해야 합니다.

WebRTC 유출

WebRTC는 proxy를 통해 라우팅하더라도 실제 IP 주소를 노출할 수 있습니다. STUN 요청이 HTTP proxy 설정을 우회하고 직접 연결하여 원본 IP를 드러냅니다. 이 문제는 애플리케이션 코드가 아니라 브라우저 레벨에서 처리해야 합니다.


3계층: 행동 패턴

1-2 계층을 인프라 레벨에서 처리했다면, 3계층부터는 애플리케이션 코드의 영역입니다.

anti-bot 시스템은 세션이 페이지와 어떻게 상호작용하는지를 추적합니다. 실제 사용자는 스크립트처럼 행동하지 않습니다. 페이지 로드 5ms 만에 요소를 클릭하지 않고, 일정한 500px/s로 스크롤하지 않으며, 60초 동안 200개 페이지를 유휴 시간 없이 방문하지 않습니다.

구현해야 할 것들

액션 간 랜덤 딜레이. 고정된 sleep(2000)이 아니라, 액션 유형별로 달라지는 랜덤 범위를 사용합니다.

import random
import asyncio

async def human_delay(min_ms=800, max_ms=2500):
    delay = random.uniform(min_ms, max_ms) / 1000

사실적인 마우스 이동. 순간이동하지 말고 요소까지 커서를 이동시킨 뒤 클릭합니다. 일부 anti-bot 시스템은 마우스 이벤트 시퀀스를 추적하며, 선행 mousemove 이벤트 없이 발생하는 클릭을 플래깅합니다.

async def move_and_click(page, selector):
    element = await page.query_selector(selector)
    box = await element.bounding_box()
    # Move to element with some randomness in the endpoint
    x = box["x"] + box["width"] * random.uniform(0.3, 0.7)

스크롤 패턴. 요소 위치까지 한 번에 이동하지 말고 점진적으로 스크롤합니다. 실제 사용자는 목표 지점을 지나쳤다가 다시 올라오기도 합니다.

요청 간격 조절. 같은 도메인에 요청을 보낸다면, 크롤러처럼 보이지 않도록 간격을 두세요. 대부분의 사이트에서 페이지 이동 간 2-5초가 합리적인 기준선입니다.


4계층: 세션 관리

마지막 계층은 상태입니다. anti-bot 시스템은 시간에 걸쳐 세션을 추적하고, 실제 사용자가 절대 만들어내지 않을 패턴을 플래깅합니다.

쿠키 유지

실제 브라우저는 여러 번의 방문에 걸쳐 쿠키를 축적합니다. 쿠키가 전혀 없는 상태로 도착해서 전부 수락한 뒤, 5분 뒤에 다시 쿠키 없이 나타나면 자동화임이 명백합니다. 격리된 브라우저 프로필을 사용하여 실행 간에 쿠키 상태를 유지하세요.

로그인 상태 유지

자동화가 계정에 로그인한다면 그 세션을 유지해야 합니다. 로그인-작업 하나 수행-로그아웃을 다른 fingerprint로 반복하면 계정이 플래깅됩니다.

세션 격리

여러 동시 세션을 실행할 때(다른 섹션 스크래핑, 다중 계정 관리 등), 각 세션은 자체 격리된 컨텍스트가 필요합니다. 별도의 쿠키, 별도의 로컬 스토리지, 별도의 fingerprint. 세션 A의 쿠키가 세션 B로 유출되는 교차 오염은 동시 자동화에서 차단의 흔한 원인입니다.

from playwright.async_api import async_playwright

async def isolated_session(profile_name, target_url):
    async with async_playwright() as p:
        # Connect to Clawbrowser with an isolated profile

자체 속도 제한

단일 타겟에 대한 요청 패턴을 모니터링하세요. 같은 도메인에 시간당 1,000건의 요청을 보내고 있다면 아무리 fingerprint를 관리해도 소용없습니다. 도메인별로 합리적인 한도를 설정하고, 임계값에 접근하면 세션을 교체하세요. 이 방법은 요청 부하를 여러 계정에 분산시키는 것으로 구현할 수 있으며, 각 계정에 별도의 브라우저 프로필과 proxy를 할당합니다.


전체 구성

1-2 계층은 인프라 영역입니다. 애플리케이션 코드에서 해결할 문제가 아닙니다. 관리된 fingerprint와 내장 proxy 라우팅을 갖춘 anti-detect browser가 두 계층을 엔진 레벨에서 처리하므로, 여러분의 코드는 3-4 계층에만 집중하면 됩니다.

Clawbrowser는 이러한 인프라 계층을 처리하는 Chromium 포크입니다. 20개 이상 표면에 걸친 엔진 레벨 fingerprint 패치, 지리적 정합성을 갖춘 내장 proxy 라우팅, WebRTC 유출 방지, 네이티브 CDP 지원을 제공합니다. Playwright나 Puppeteer 코드가 일반 Chrome 인스턴스처럼 연결됩니다.

from playwright.async_api import async_playwright
import random, asyncio

async def scrape_with_clawbrowser():
    async with async_playwright() as p:

clawbrowser.ai에서 설치 프롬프트를 복사하여 AI 에이전트에 붙여넣기만 하면 됩니다. 설정은 2분 이내에 완료됩니다.

각 계층은 독립적입니다. 차단되고 있다면 어느 계층이 원인인지 진단하세요. fingerprint가 깨끗하고 IP가 플래깅되지 않은 것을 확인했다면 문제는 행동 코드나 세션 관리에 있습니다. 행동이 사실적인데도 여전히 차단된다면 문제는 브라우저 identity나 네트워크 계층에 있습니다. 아래에서 위로 작업하세요.

CAPTCHA가 나타날 때 단계별 진단 방법은 자동화에서 CAPTCHA가 반복되는 이유: 7가지 신호 진단 가이드를 참고하세요.


효과 없는 방법과 그 이유

접근법 실패 이유
--headless 플래그 headed Chrome과 다른 fingerprint를 생성합니다. 많은 사이트가 headless를 즉시 차단합니다.
stealth 플러그인 페이지 레벨에서 신호를 패치합니다. 엔진 레벨 신호는 그대로 노출됩니다. 출시 후 수개월 내에 탐지됩니다.
랜덤 User-Agent 교체 20개 이상 신호 중 1개만 변경합니다. 다른 fingerprint 신호와 불일치를 만듭니다.
IP만 교체 2계층은 수정하지만 1계층은 열려 있습니다. 깨끗한 IP라도 브라우저 identity가 유출되면 차단됩니다.
모든 곳에 sleep(5) 추가 3계층의 한 가지 측면만 수정합니다. 1, 2 계층과 3계층의 나머지는 방치됩니다.

공통 패턴: 각 접근법이 한 계층의 하나의 신호만 수정합니다. anti-bot 시스템은 네 계층을 동시에 검사합니다. 부분적 수정은 프로덕션에서 살아남지 못합니다.


FAQ

Cloudflare가 Playwright를 탐지할 수 있나요?

네. 기본 Chromium에서 실행되는 일반 Playwright는 Cloudflare의 Turnstile과 Bot Management에 수초 내에 탐지됩니다. 탐지는 주로 1계층(브라우저 identity)에서 이루어집니다. navigator.webdriver, CDP 아티팩트, WebGL 렌더링 차이, TLS fingerprint가 원인입니다. 상세 분석은 Playwright 스크립트가 Cloudflare에 차단되는 이유와 해결 방법을 참고하세요.

Residential proxy가 필요한가요?

공격적인 anti-bot 시스템을 사용하는 사이트라면 필요합니다. 데이터센터 IP는 anti-bot 업체에 의해 목록화되어 있고 더 높은 검증을 받습니다. 실제 ISP의 residential proxy는 차단율을 크게 낮춥니다. 다만 residential IP라도 브라우저 fingerprint가 유출되면 여전히 차단됩니다. proxy는 2계층을 수정할 뿐, 1계층은 아닙니다.

Headless 모드는 항상 탐지되나요?

최신 headless Chrome(--headless=new)은 이전 headless 구현보다 headed 모드에 가깝지만, GPU 렌더링, 화면 메트릭, 글꼴 가용성에서 차이가 남아 있습니다. Cloudflare, Akamai, DataDome 같은 정교한 탐지 시스템은 여전히 headless 세션을 구별할 수 있습니다. 높은 가치의 타겟에는 적절한 anti-detect browser를 사용한 headed 모드가 안정적인 선택입니다.

차단 없이 얼마나 빠르게 스크래핑할 수 있나요?

범용적인 수치는 없습니다. 타겟 사이트의 속도 제한과 탐지 민감도에 따라 다릅니다. 합리적인 시작점은 같은 도메인에서 페이지 이동 간 2-5초이며, 그 범위 내에서 랜덤화합니다. 차단율을 모니터링하고 증가하면 속도를 줄이세요. 일부 사이트는 초당 1회 요청을 허용하고, 다른 사이트는 단일 세션에서 10초에 1회 이상이면 플래깅합니다.

AI 에이전트의 브라우저 자동화에도 동일한 탐지 문제가 있나요?

네. Claude Code, Codex, Cursor, Hermes Agent 같은 AI 에이전트 프레임워크는 CDP를 통해 브라우저를 제어합니다. anti-bot 시스템이 확인하는 것은 브라우저 identity이며, 명령이 사람에게서 오든 에이전트에게서 오든 상관없습니다. 기본 Chrome 인스턴스에 연결하는 AI 에이전트는 Playwright 스크립트와 동일한 이유로 차단됩니다. 에이전트 전용 설정은 CDP Browser for AI Agents: 개발자 가이드를 참고하세요.


결론: 아래에서부터 쌓아 올리세요

브라우저 자동화가 차단되는 이유는 anti-bot 시스템이 네 계층을 검사하는데 대부분의 자동화는 한두 계층만 다루기 때문입니다. 아래에서 위로 수정하세요. 브라우저 identity를 먼저, 그 다음 네트워크, 그 다음 행동, 그 다음 세션. 처음 두 계층은 코드가 아니라 브라우저에 속하는 인프라 문제입니다.

clawbrowser.ai에서 설치 프롬프트를 복사하여 AI 에이전트에 붙여넣기만 하면 됩니다. 설정은 2분 이내에 완료됩니다.

그 다음 코드에서 3-4 계층에 집중하세요. 사실적인 타이밍, 마우스 이동, 세션 격리, 속도 관리. 이것이 프로덕션에서 유지되는 스택입니다.

계속 읽기

모든 글 보기 →