봇이 전체 웹 트래픽의 51%를 차지합니다. 웹사이트들은 이를 인지하고 대응하고 있습니다. Cloudflare, Akamai, DataDome의 봇 방지 시스템은이제 IP 평판, TLS 지문 인식, 브라우저 지문 인식, 행동 분석을 결합하여 HTML 한 줄도 반환되기 전에 스크레이퍼를 차단합니다. 스크레이퍼가 계속 차단된다면, 이 가이드는 정확한 이유를 설명하고 이를 해결하기 위한 12가지 구체적인 기법을 제공합니다.
간단 요약: 차단당하지 않고 스크래핑하는 방법
- 주거용 프록시를 이용해 IP 주소를 순환하세요. 데이터센터 IP는 쉽게 탐지됩니다.
User-Agent및Referer를포함한 완전한 브라우저 유사 HTTP 헤더를 설정하세요.- 2~10초 간격으로 요청 타이밍을 무작위화하세요.
- 지문 검사를 통과하기 위해 스텔스 플러그인이 적용된 헤드리스 브라우저를 사용하세요.
- 수동 해결은 확장성이 없으므로 CAPTCHA를 자동으로 처리하세요.
- 대상 사이트의 예상 사용자 기반에 맞춰 프록시 지리적 위치를 조정합니다.
- 관리형 스크래핑 API(예: Bright Data의 Web Unlocker)를 사용하여 위의 모든 작업을 자동화합니다.
웹사이트가 스크래퍼를 차단하는 이유
차단을 받는 이유를 이해하는 것이 차단되지 않는 첫걸음입니다. 감지는 페이지 다운로드 후 발생하지 않습니다. HTML이 제공되기 전, 연결 초기 몇 밀리초 내에 발생하는 경우가 많습니다. 가장 흔한 반스크래핑 기법은 계층적 조합으로 작동하며, 이를 우회하려면 모든 계층을 동시에 일치시켜야 합니다.
IP 기반 탐지
사용자가 보내는 모든 요청에는 소스 IP 주소가 포함됩니다. 안티봇 시스템은 알려진 데이터센터 IP 범위(AWS, GCP, Azure, DigitalOcean), 이전에 플래그가 지정된 IP, 높은 요청량을 보이는 IP에 대한 평판 데이터베이스를 유지합니다. 분당 500개의 요청을 보내는 단일 IP는 쉽게 식별됩니다. 많은 고보안 사이트에서는 기본적으로 데이터센터 IP를 차단합니다. 실제 주거용 사용자가 AWS 데이터센터에서 접속하는 경우는 없기 때문입니다.
브라우저 및 TLS 지문 인식
모든 HTTPS 연결은 TLS 핸드셰이크로 시작됩니다. ClientHello 단계에서 클라이언트는 콘텐츠 교환 전에 지원하는 암호화 스위트, TLS 버전, 확장 기능, 타원 곡선 선호도를 모두 평문으로 전송합니다. 안티봇 시스템은 이 데이터를 해시하여 지문(JA3 또는 JA4 표준)을 생성하고, 이를 알려진 봇 시그니처와 비교합니다. Python의 requests 라이브러리는 실제 브라우저와는 다른 독특한 TLS 지문을 가지며, Cloudflare와 Akamai에 의해 쉽게 탐지됩니다.
TLS 외에도 웹사이트는 수십 가지 자바스크립트 신호를 통해 브라우저 유형을 감지합니다: navigator.webdriver, 캔버스 렌더링 출력, WebGL GPU 문자열, 설치된 폰트, 화면 해상도, 오디오 컨텍스트 동작, 플러그인 목록 등이 있습니다. 헤드리스 크롬은 사용자 에이전트 문자열에 HeadlessChrome을 노출하고 navigator.webdriver = true를 설정된 상태로 남겨두는데, 이는 대부분의 주요 봇 방지 플랫폼에서 즉각적인 탐지 신호입니다.
행동 분석
웹사이트는 개별 요청만 살펴보지 않습니다. 전체 세션에 걸친 패턴을 관찰합니다. PerimeterX/HUMAN 및 유사 시스템은 요청 간 타이밍, 스크롤 패턴, 마우스 이동 궤적, 클릭 행동, 탐색 깊이, 세션 지속 시간을 측정합니다. 정확히 1.0초 간격으로 요청을 발사하고, 절대 스크롤하지 않으며, 마우스를 움직이지 않고, 홈페이지를 방문하지 않은 채 깊숙한 제품 페이지로 바로 이동하는 스크레이퍼는 인간과 즉시 구분됩니다.
CAPTCHA 및 자바스크립트 검증
사이트가 자동화를 의심하지만 확실하지 않을 때, 챌린지를 발행합니다. Cloudflare Turnstile, reCAPTCHA v3, hCaptcha는 자동화 흔적을 확인하는 자바스크립트 프로브를 실행합니다. 이러한 챌린지에 실패하거나 자바스크립트 실행 자체가 불가능한 경우, 차단되거나 무한 리디렉션 루프에 빠지게 됩니다.
허니팟 트랩
일부 사이트는 HTML에 숨겨진 링크를 삽입합니다. 실제 사용자에게는 CSS(display: none)로 보이지 않지만, 원시 HTML을 파싱하는 스크레이퍼에게는 완전히 접근 가능합니다. 이러한 링크를 따라가면 즉시 봇으로 식별됩니다. 문서 내 모든 <a href> 태그를 무분별하게 따라가는 스크레이퍼는 결국 이런 링크에 걸리게 됩니다.
차단되지 않고 웹사이트를 스크래핑하는 최상위 기법
1. 프록시를 통한 IP 주소 회전
IP 회전은 가장 기본적인 탐지 방지 기술입니다. 단일 IP 주소에서 모든 요청을 보내는 대신, 프록시 풀은 수백 또는 수천 개의 IP에 트래픽을 분산시켜 단일 IP가 의심스러운 요청량을 축적하지 않도록 합니다. Python에서 프록시를 회전하는 방법을 배우는 것은 본격적인 스크레이퍼를 구축하는 모든 사람에게 필수적인 기술입니다.
기본 패턴: 각 요청을 서로 다른 프록시 엔드포인트로 라우팅하고, IP가 차단될 경우 자동 재시도 로직을 구현합니다.
import requests
from itertools import cycle
import random
import time
proxies = [
"http://proxy1.example.com:8080",
"http://proxy2.example.com:8080",
"http://proxy3.example.com:8080",
]
proxy_pool = cycle(proxies)
def fetch(url):
proxy = next(proxy_pool)
try:
response = requests.get(
url,
proxies={"http": proxy, "https": proxy},
timeout=10
)
response.raise_for_status()
return response.text
except requests.exceptions.RequestException as e:
print(f"프록시 {proxy} 실패: {e}")
return None
# 요청 간 무작위 지연 추가로 속도 제한 회피
time.sleep(random.uniform(2, 6))
대량 작업에는 단순한 라운드 로빈 방식 이상의 것이 필요합니다. 지능적인 세션 관리, 자동 IP 폐기, 지역 기반 선택이 필요합니다. 그래서 실제 스크래퍼는 정적 목록 대신 관리형 프록시 인프라를 사용합니다.
2. 주거용 또는 모바일 프록시 사용
모든 프록시가 동등하지는 않습니다. 데이터센터 프록시와 주거용 프록시는 비용과 탐지 위험 사이의 근본적인 절충점을 나타냅니다. 데이터센터 프록시는 클라우드 서버 IP를 통해 트래픽을 라우팅합니다: 빠르고 저렴하지만, ASN 차단 목록을 가진 모든 봇 방지 시스템에 의해 즉시 비인간으로 식별됩니다.
주거용 프록시는 실제 가정 및 업무용 연결에 할당된 ISP IP 주소를 통해 트래픽을 라우팅합니다. 대상 사이트에는 특정 도시의 특정 ISP를 사용하는 실제 사용자로부터 요청이 발생한 것처럼 보입니다. 모바일 프록시는 실제 이동통신사 IP(4G/5G)를 통해 트래픽을 라우팅하여 한 걸음 더 나아갑니다. 이동통신사는 CGNAT(여러 실제 사용자가 하나의 IP를 공유)를 사용하기 때문에 블랙리스트에 오를 가능성이 훨씬 낮습니다.
| 프록시 유형 | 탐지 가능성 | 속도 | 최적 용도 |
|---|---|---|---|
| 데이터센터 | 높음 | 매우 빠름 | 보안 수준이 낮은 사이트, 대용량 |
| ISP/정적 주거용 | 중간 | 빠름 | 일관된 신원, 계정 기반 스크래핑 |
| 주거용 | 낮음 | 중간 | 전자상거래, 여행, 소셜 플랫폼 |
| 모바일 | 매우 낮음 | 중간 | 모바일 전용 콘텐츠, 공격적인 사이트 |
Bright Data는 195개 이상의 국가에 걸쳐 1억 5천만 개 이상의 주거용 IP 네트워크를 운영하며, 윤리적으로 확보된 최대 규모의 프록시 네트워크를 제공합니다. 주거용 IP조차 차단되는 상황에서 700만 개 이상의 모바일 IP가 가능한 최고 수준의 신뢰 신호를 제공합니다.
3. 현실적인 요청 헤더 설정
Python의 requests 라이브러리는 기본적으로 최소한의 헤더만 전송합니다. 실제 Chrome 브라우저와 비교하면 차이가 즉시 드러납니다:
# requests가 기본적으로 전송하는 내용:
User-Agent: python-requests/2.31.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
# Chrome 121이 실제로 전송하는 내용:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8
Accept-Language: en-US,en;q=0.9
Accept-Encoding: gzip, deflate, br, zstd
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
사이트는 Accept, Accept-Language, Accept-Encoding, Sec-Fetch-* 헤더 및 헤더 순서를 확인하여 실제 브라우저와 스크립트를 구분합니다. 동일한 도메인 내 페이지 간 이동 시 Referer 헤더를 포함하여, 자신이 주장하는 실제 브라우저와 일치하는 헤더를 설정하세요. 더 자세한 내용은 웹 스크래핑을 위한 HTTP 헤더 가이드를 참조하세요.
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
"Referer": "https://www.google.com/",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "cross-site",
"Upgrade-Insecure-Requests": "1",
}
response = requests.get(url, headers=headers)
4. 사용자 에이전트 순환
모든 요청에 동일한 User-Agent 문자열을 보내는 것도 쉽게 노출되는 신호입니다. 실제 사용자들이 모두 Windows 10에서 Chrome 121을 실행하지는 않습니다. 현실적이고 최근에 활동한 User-Agent 문자열 풀을 구축하고 이를 순환하세요. 핵심 규칙: 순환하는 User-Agent는 내부적으로 일관성이 있어야 합니다. macOS에서 Chrome이라고 주장한다면, Accept-Language 및 Sec-CH-UA 헤더도 이를 반영해야 합니다.
import random
user_agents = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Mozilla/5.0 (X11; Linux x86_64; rv:122.0) Gecko/20100101 Firefox/122.0",
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1",
]
headers["User-Agent"] = random.choice(user_agents)
사용자 에이전트 풀을 최신 상태로 유지하세요. 2021년 브라우저 버전은 2026년 실제 트래픽을 대표할 가능성이 통계적으로 낮기 때문에 그 자체로 탐지 신호가 됩니다.
5. TLS 지문 관리
이것은 가장 흔히 간과되는 기법이며, 다른 모든 것을 제대로 수행한 스크레이퍼를 무력화시키는 요소입니다.
Python의 requests 라이브러리가 HTTPS 연결을 시작할 때, 기본 TLS 스택(OpenSSL 등)은 특정 암호화 스위트와 확장 기능 조합을 포함한 ClientHello를 전송합니다. 이 조합은 브라우저와 뚜렷이 구별되는 JA3 값으로 해시됩니다. Cloudflare, Akamai, DataDome은 콘텐츠 제공 전에 이 지문을 확인하므로, 헤더가 평가되기 전에 차단될 수 있습니다.
해결책: 실제 브라우저의 TLS 스택을 모방하는 HTTP 클라이언트를 사용하세요. Python의 현재 표준은 curl_cffi입니다:
from curl_cffi import requests as curl_requests
# impersonate="chrome121"은 curl_cffi가 Chrome 121의 정확한
# TLS 암호 모음, 확장 기능 및 HTTP/2 설정을 사용하도록 지시합니다
response = curl_requests.get(
"https://example.com",
impersonate="chrome121",
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ...",
})
print(response.status_code)
curl_cffi는 암호화 수준에서 실제 브라우저 TLS 지문을 모방하는 libcurl 빌드인 curl-impersonate를 래핑합니다. 핵심 요구사항: 사용자 에이전트(User-Agent)는 모방하려는 브라우저 프로필과 일치해야 합니다. Firefox 사용자 에이전트와 함께 Chrome 121 TLS 지문을 전송하면 고급 시스템이 감지하는 불일치가 발생합니다.
실제 운영 환경에서는 Bright Data의 Web Unlocker가 TLS 지문 일치를 자동으로 처리하므로 별도의 라이브러리 관리가 필요하지 않습니다.
6. 스텔스 플러그인이 적용된 헤드리스 브라우저 사용
대상 사이트가 자바스크립트 검증을 수행할 경우 실제 브라우저가 필요합니다. 헤드리스 브라우저의 개념과 작동 방식을 이해하는 것이 이 기법의 기초가 됩니다. Playwright와 Puppeteer는 크로미움을 자동화하여 완전한 자바스크립트 실행, 쿠키 처리, 동적 콘텐츠 렌더링을 가능하게 합니다.
문제점: 기본 헤드리스 Chrome은 쉽게 탐지됩니다. navigator.webdriver = true 노출, HeadlessChrome 사용자 에이전트 문자열, 누락된 브라우저 플러그인, 비정상적인 화면 크기가 드러납니다. Cloudflare의 Turnstile 및 유사 시스템은 200개 이상의 JavaScript 검사를 실행하며 기본 Playwright 세션을 수 밀리초 내에 포착합니다.
해결책은 이러한 탐지 벡터를 패치하는 플러그인인 playwright-stealth입니다:
from playwright.sync_api import sync_playwright
from playwright_stealth import stealth_sync
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
# navigator.webdriver, 크롬 런타임, iframe 콘텐츠 윈도우,
# 미디어 코덱 및 기타 자동화 흔적 패치
stealth_sync(page)
page.goto("https://example.com")
print(page.title())
browser.close()
playwright-stealth는 가장 흔한 탐지 벡터인 navigator.webdriver, window.chrome, navigator.plugins, navigator.languages 및 권한 API 불일치를 처리합니다. Selenium 사용자의 경우, undetected-chromedriver가 이에 상응하며 ChromeDriver를 바이너리 수준에서 패치합니다.
중요한 제한 사항: 스텔스 플러그인은 탐지 위험을 줄이지만 완전히 제거하지는 않습니다. Cloudflare Turnstile과 Akamai Bot Manager는 크게 진화하여 패치된 헤드리스 브라우저도 여전히 탐지할 수 있습니다. 최대의 안정성을 위해 Bright Data의 Scraping Browser는 이러한 검사를 플러그인 설정 없이도 즉시 통과하도록 특별히 구축된 사전 강화된 브라우저 환경입니다.
7. 요청 타이밍 및 행동 무작위화
고정된 간격(넉넉한 간격이라도)으로 요청을 발사하는 스크레이퍼는 타이밍 분석으로 탐지 가능합니다. 실제 사용자는 2.0초마다 페이지를 방문하지 않습니다. 그들은 읽고, 스크롤하고, 클릭하며, 멈추고, 비선형적으로 탐색합니다.
지연 시간에 가우시안(정규) 분포를 적용하세요. 이는 대부분의 지연이 평균값 주변에 집중되지만 가끔 길어지는 인간과 유사한 변동성을 생성합니다:
import numpy as np
import time
import random
def human_delay(mean=4.0, std=1.5, min_delay=1.0):
"""정규 분포를 사용해 인간과 유사한 지연 시간 생성"""
delay = np.random.normal(mean, std)
# 최소값 미만 발생 방지
delay = max(delay, min_delay)
time.sleep(delay)
# 페이지 요청 간
human_delay(mean=4.0, std=1.5)
# 동일 페이지 내 작업 간 (더 빠른 지연)
human_delay(mean=1.2, std=0.4)
타이밍 외에도 Playwright로 현실적인 세션 동작을 시뮬레이션하세요: 데이터 추출 전 페이지 점진적 스크롤, 클릭 전 마우스 요소 이동, 항상 대상 URL로 직접 이동하지 않고 크롤링 진입점을 다양화하세요.
# 콘텐츠 추출 전 인간 스크롤 행동 시뮬레이션
page.evaluate("window.scrollTo(0, document.body.scrollHeight * 0.3)")
time.sleep(random.uniform(0.8, 2.0))
page.evaluate("window.scrollTo(0, document.body.scrollHeight * 0.7)")
time.sleep(random.uniform(0.5, 1.5))
8. CAPTCHA 자동 처리
CAPTCHA는 벽이지 막다른 길이 아니지만, 수동 해결은 확장성이 부족합니다. 실제 스크래핑 작업에는 자동화된 CAPTCHA 처리가 필요합니다. 웹 스크래핑용 최고의 CAPTCHA 솔버를 검토하면 사용 사례에 맞는 도구를 선택하는 데 도움이 될 것입니다.
주요 접근법:
- 타사 해결 서비스 (2captcha, Anti-Captcha): CAPTCHA 이미지 또는 사이트 키를 인간 해결사나 AI 모델에 전송하고, 토큰을 수신하여 양식에 주입합니다.
- reCAPTCHA v3 점수 관리: reCAPTCHA v3는 백그라운드에서 실행되며 위험 점수를 부여합니다. 점수가 높을수록 챌린지 화면이 표시될 확률이 낮아지므로, 세션 위생 관리(현실적인 헤더, 타이밍, 브라우징 기록)를 통해 점수를 높게 유지하세요.
- 관리형 솔루션: Bright Data의 Web Unlocker에는 reCAPTCHA, hCaptcha, Cloudflare Turnstile을 별도의 통합 없이 투명하게 처리하는 내장형 CAPTCHA 솔버가 포함되어 있습니다.
import requests
# Bright Data Web Unlocker 사용 시, 응답 반환 전에 CAPTCHA가 자동으로 해결됩니다.
# 별도의 솔버 통합이 필요하지 않습니다.
response = requests.get(
"https://target-site.com/product-page",
proxies={
"https": "https://username:[email protected]:33335"
},
verify=False # Web Unlocker 자체 SSL 인증서 사용
)
print(response.status_code) # 완전히 렌더링된 콘텐츠와 함께 200을 반환합니다
9. 허니팟 함정 피하기
허니팟 링크는 실제 사용자에게는 보이지 않지만 원시 HTML에서는 확인됩니다. 이를 따라가는 것은 즉시 봇 신호로 간주됩니다.
링크를 따라가기 전에 CSS 가시성을 확인하여 탐지하세요:
from bs4 import BeautifulSoup
def is_visible(tag):
"""요소가 CSS로 숨겨진 경우 False를 반환합니다."""
style = tag.get("style", "")
if "display:none" in style.replace(" ", "") or
"visibility:hidden" in style.replace(" ", ""):
return False
# 일반적인 허니팟 클래스명도 확인
classes = tag.get("class", [])
honeypot_classes = {"hidden", "invisible", "honeypot", "trap"}
if honeypot_classes.intersection(set(classes)):
return False
return True
soup = BeautifulSoup(html_content, "html.parser")
safe_links = [
a["href"] for a in soup.find_all("a", href=True)
if is_visible(a)
]
이 방법은 모든 허니팟을 포착하지 못합니다. 일부는 인라인 스타일이 아닌 외부 CSS 클래스를 통해 숨겨지기 때문입니다. Playwright의 page.is_visible() 메서드는 인라인 속성만 평가하는 것이 아니라 계산된 CSS 스타일을 평가하므로 더 신뢰할 수 있습니다.
10. 지수적 백오프를 통한 속도 제한 처리
HTTP 429(Too Many Requests) 응답의 경우 즉시 재시도는 역효과를 냅니다 — 차단 속도를 가속화합니다. 지수적 백오프를 구현하여 우아하게 속도를 늦추고 더 강력한 차단 없이 스크래핑을 재개하세요:
import time
import random
import requests
def fetch_with_backoff(url, headers, proxies, max_retries=5):
"""속도 제한 응답 시 지수적 백오프 재시도"""
for attempt in range(max_retries):
response = requests.get(url, headers=headers, proxies=proxies, timeout=15)
if response.status_code == 200:
return response
elif response.status_code == 429:
# Retry-After 헤더가 존재할 경우 준수
retry_after = int(response.headers.get("Retry-After", 2 ** attempt))
print(f"속도 제한. {retry_after}초 대기 중 ({attempt + 1}번째 시도))")
time.sleep(retry_after)
elif response.status_code in (403, 503):
# 차단된 것으로 추정, IP 회전 후 대기
print(f"차단됨 (HTTP {response.status_code}). 백오프 중...")
time.sleep(2 ** attempt + random.uniform(0, 1))
else:
response.raise_for_status()
raise Exception(f"{url}에 대한 최대 재시도 횟수 초과")
11. 지리적 컨텍스트 일치
많은 사이트는 요청의 지리적 출처에 따라 다른 콘텐츠를 제공하거나 더 엄격한 봇 탐지를 시행합니다. 미국 전자상거래 사이트를 대상으로 하는 제품 가격 스크래퍼는 독일이나 싱가포르 IP가 아닌 미국 주거용 IP를 통해 요청을 라우팅해야 합니다. 지리적 불일치는 요청 출처와 Accept-Language 또는 locale 헤더 간의 불일치를 생성하며, 이는 행동 분석 시스템이 감지할 수 있습니다.
Bright Data의 프록시 네트워크는 국가, 주, 도시, 통신사별 타겟팅을 지원하여 대상 사이트가 기대하는 정확한 지리적 컨텍스트에서 요청이 발생하도록 합니다. 지리적 타겟팅 전략을 수립하기 전에 사용 가능한 모든 프록시 IP 위치를 탐색할 수 있습니다.
12. 기본 API 활용하기
복잡한 스크레이퍼를 구축하기 전에 대상 사이트가 프론트엔드에서 사용하는 내부 API를 노출하는지 확인하세요. 브라우저 개발자 도구를 열고 네트워크 탭으로 이동한 후 사이트를 탐색하면서 XHR/Fetch 요청을 관찰하세요. 대형 이커머스 플랫폼을 포함한 많은 사이트는 HTML을 파싱하는 것보다 직접 호출하기 훨씬 쉬운 JSON 엔드포인트에서 데이터를 로드합니다.
이러한 내부 API는 구조화된 JSON 응답(HTML 파싱 불필요), 메인 렌더링 페이지보다 낮은 봇 차단 수준, 자동화가 쉬운 페이지네이션 매개변수를 제공하는 경우가 많습니다.
단점: 내부 API는 문서화되지 않았으며, 사전 공지 없이 변경될 수 있고, 메인 사이트를 통해 획득해야 하는 인증 토큰이 필요할 수 있습니다. 하지만 이용 가능하고 안정적일 때, 이는 가장 효율적인 스크래핑 경로입니다.
가장 빠른 방법: 웹 스크래핑 API 사용
위 12가지 기법은 모두 개별 구현, 유지보수, 그리고 봇 방지 시스템의 진화에 따른 지속적인 적응이 필요합니다. 규모가 커지면 이 스택을 관리하는 것이 본업이 됩니다.
대안: 전체 스택을 단일 API 호출로 통합하세요.
Bright Data 웹 언락커
웹 언락커는 AI 기반 프록시 게이트웨이로, 대상 사이트 요구사항에 따라 IP 회전, TLS 지문 일치, CAPTCHA 해결, 브라우저 렌더링을 자동 처리합니다. 표준 HTTP 요청만 보내면 됩니다. 웹 언락커가 사용할 프록시 유형, 제시할 지문, CAPTCHA 해결 여부, 자바스크립트 렌더링 여부를 결정한 후 사이트의 반봇 복잡도와 무관하게 깨끗한 콘텐츠를 반환합니다.
import requests
response = requests.get(
"https://any-protected-site.com/data",
proxies={"https": "https://user:[email protected]:33335"},
verify=False,)
# 완전히 렌더링되고 차단되지 않은 콘텐츠 반환
print(response.text)
Web Unlocker는 Cloudflare, Akamai, DataDome, PerimeterX에 대해 테스트 및 지속적으로 업데이트됩니다. 하나의 API 호출로 10가지 수동 기술을 대체합니다.
Bright Data 스크래핑 브라우저
다단계 흐름, 로그인 시퀀스, 자바스크립트 중심의 SPA(단일 페이지 애플리케이션) 등 완전한 브라우저 상호작용이 필요한 사이트의 경우, 스크래핑 브라우저는 CDP를 통해 접근 가능한 사전 강화된 크로미움 인스턴스를 제공합니다. Playwright 및 Puppeteer와 직접 통합되며, 플러그인 설정 없이도 Cloudflare Turnstile 및 Akamai Bot Manager의 지문 인식 검사를 통과합니다.
from playwright.sync_api import sync_playwright
SBR_WS_CDP = "wss://brd-customer-XXXX:[email protected]:9222"
with sync_playwright() as pw:
browser = pw.chromium.connect_over_cdp(SBR_WS_CDP)
page = browser.new_page()
page.goto("https://cloudflare-protected-site.com")
print(page.inner_text("body"))
browser.close()
Bright Data 스크레이퍼 API
스크래핑 인프라를 작성하거나 유지 관리할 필요 없이 특정 플랫폼의 구조화된 데이터가 필요한 팀을 위해 Bright Data의 Scraper API는 가장 인기 있는 도메인(Amazon, LinkedIn, Instagram, Zillow, Indeed, TikTok, Walmart, Booking.com, Glassdoor 등)을 위한 120개 이상의 즉시 사용 가능한 스크레이퍼 라이브러리를 제공합니다.
각 스크레이퍼는 URL 또는 키워드 입력을 받아 내부적으로 모든 차단 해제 및 렌더링을 처리한 후 JSON 또는 CSV 형식의 깔끔한 구조화된 데이터를 반환합니다. 프록시 관리, 파서 유지보수, 지문 조정 등이 필요하지 않습니다. 성공적으로 전달된 레코드에 대해서만 비용을 지불합니다.
# 예시: 스크레이퍼 API를 통해 아마존 제품 스크래핑 실행
curl -H "Authorization: Bearer API_TOKEN"
-H "Content-Type: application/json"
-d '[{"url":"https://www.amazon.com/dp/B0CRMZHDG8","asin":"B0CRMZHDG8","zipcode":"94107"}]'
"https://api.brightdata.com/datasets/v3/trigger?dataset_id=gd_l7q7dkf244hwjntr0&format=json"
전자상거래 플랫폼, LinkedIn 및 소셜 미디어 채널용 전용 스크레이퍼를 제공하며, 결과는 웹훅, API 폴링 또는 직접 다운로드를 통해 전달됩니다. 아직 지원되지 않는 도메인의 경우, Scraper Studio를 사용하면 인프라 작업 없이 AI를 활용해 맞춤형 스크레이퍼를 구축할 수 있습니다.
Bright Data 주거용 프록시
자체 스크래핑 인프라를 관리하지만 안정적이고 대규모 IP 풀이 필요한 경우: Bright Data의 주거용 프록시 네트워크는 195개 이상의 국가에 걸쳐 1억 5천만 개 이상의 IP를 커버하며, 도시 및 통신사 수준까지 세분화된 지리적 타겟팅이 가능합니다. 여기에는 모바일 통신사 트래픽용 700만 개 이상의 모바일 IP와 높은 신뢰도 점수를 가진 정적 주거용 IP용 ISP 프록시가 포함됩니다.
안티봇 시스템: 맞서야 할 상대
Cloudflare
Cloudflare Bot Management는 가장 광범위하게 배포된 봇 방지 시스템으로, 주요 전자상거래 및 미디어 사이트를 포함한 수백만 사이트를 보호합니다. 이 시스템은 JavaScript 챌린지(Turnstile 포함), IP 평판 점수, TLS/JA4 지문 인식, 행동 분석 등 다층적으로 작동합니다. Cloudflare의 cf_clearance 쿠키는 실제 브라우저에서 챌린지를 통과하여 획득한 후 TTL 내에서 재사용할 수 있습니다. 탐지는 navigator.webdriver 노출, 일관성 없는 헤더 세트, 비브라우저 JA4 해시에 크게 의존합니다. 효과적인 방법에 대한 완전한 기술적 안내는 Cloudflare 우회 방법 가이드를 참조하십시오.
Akamai Bot Manager
Akamai는 주입된 JavaScript를 통해 클라이언트 측 센서 데이터(캔버스, 폰트, 타임존, WebGL)를 수집하고 서버 측에서 abck 쿠키 토큰과 대조하여 검증합니다. TLS/JA3 지문과 세션 토큰을 동시에 교차 참조하므로 한 계층만 수정하는 것은 충분하지 않습니다. Akamai는 기업형 소매, 항공사, 금융 사이트에서 흔히 사용됩니다. 암호화 스위트 불일치만으로도 소프트 차단 또는 403 오류가 발생할 수 있습니다.
DataDome
DataDome은 실시간 머신러닝 기반 스코어링으로 브라우저 스크래핑과 API 스크래핑을 모두 차단합니다. IP ASN, 요청 빈도, 헤더 엔트로피, 클라이언트 측 자바스크립트 신호를 종합적으로 검증합니다. 검증 실패 시 “접근 거부됨. DataDome 제공.”이라는 고유한 페이지가 반환됩니다. 모바일 주거용 IP와 지속적 세션을 활용한 완전한 브라우저 자동화는 일반 HTTP 클라이언트보다 DataDome에 대해 훨씬 우수한 성능을 보입니다.
PerimeterX / HUMAN
PerimeterX (현 HUMAN Security)는 행동 분석을 전문으로 하며, 전체 세션에 걸쳐 마우스 움직임, 키 입력, 스크롤 깊이, 포커스/블러 이벤트 및 타이밍을 추적하여 행동 지문을 구축합니다. 세션을 인간 기준선과 비교하여 봇 점수를 할당합니다. 특히 지연 적용 전략을 사용하여 차단 전에 행동 증거를 축적하는 동안 의심되는 봇이 자유롭게 탐색할 수 있도록 합니다. 이는 차단이 발생하기 전까지 처음 몇 번의 요청이 성공할 수 있음을 의미합니다.
비교: 차단 메커니즘과 대응책
| 차단 메커니즘 | 권장 기법 | Bright Data 솔루션 |
|---|---|---|
| IP 차단 / 속도 제한 | 프록시를 통한 IP 회전 | 주거용 프록시 (1억 5천만 개 이상의 IP) |
| 데이터센터 IP 감지 | 주거용 또는 모바일 프록시 사용 | ISP 프록시, 모바일 프록시 |
| TLS 지문 인식 | 브라우저 사칭 기능이 있는curl_cffi |
웹 언로커 (자동 TLS 매칭) |
| 브라우저 지문 인식 | 헤드리스 브라우저 + 스텔스 플러그인 | 스크래핑 브라우저 (스텔스 내장) |
| CAPTCHA 챌린지 | 자동 CAPTCHA 해결기 | 웹 언락커 (내장 솔버) |
| 행동 분석 | 랜덤 타이밍 + 인간 행동 시뮬레이션 | 스크래핑 브라우저 (인간과 유사한 행동) |
| 허니팟 트랩 | 숨겨진 링크 건너뛰기 | 스크래핑 브라우저 (지능형 탐색) |
| 자바스크립트 검증 | 전체 브라우저 렌더링 | 스크래핑 브라우저, 웹 언락커 |
| 지리적 차단 | 지리적 타겟팅 프록시 | 195개 이상의 국가 타겟팅 |
| 속도 제한 | 지수적 백오프 | 웹 언로커(관리형 속도 제한) |
요약
모든 안티봇 시스템을 무력화하는 단일 기술은 존재하지 않습니다. 현대적인 탐지 시스템은 IP 평판, TLS 지문 인식, 브라우저 지문 인식, 행동 분석 등 여러 계층으로 구성되어 있으며, 이를 우회하려면 모든 계층을 동시에 통과해야 합니다.
개발 및 소량 스크래핑의 경우: 주거용 프록시, 현실적인 헤더, TLS 지문 관리를 위한 curl_cffi, 자바스크립트 중심 사이트를 위한 Playwright와 playwright-stealth로 시작하세요.
프로덕션 규모 스크래핑의 경우: 지문 회전, 스텔스 플러그인 업데이트, 프록시 풀 관리, CAPTCHA 솔버 통합 등 모든 계층을 수동으로 유지 관리하는 복잡성은 상당합니다. Bright Data의 솔루션은 IP 회전, TLS 지문 관리, CAPTCHA 해결, 브라우저 렌더링을 단일 API 호출로 통합합니다. 인프라가 아닌 데이터에 집중할 수 있는 방법입니다.
자주 묻는 질문
웹사이트가 스크래핑을 감지할 수 있나요?
예. 웹사이트는 IP 평판, HTTP 헤더 분석, TLS 지문 인식, 브라우저 지문 인식, CAPTCHA 챌린지, 행동 분석을 통해 스크레이퍼를 탐지합니다. 대부분의 탐지는 페이지 콘텐츠가 제공되기 전 밀리초 단위로 이루어집니다.
웹 스크레이퍼가 차단되는 이유는 무엇인가요?
스크레이퍼는 단일 IP에서 과도한 요청을 보내거나, 비인간적인 HTTP 헤더를 전송하거나, TLS 또는 브라우저 지문 검사에 실패하거나, CAPTCHA 도전을 유발할 때 차단됩니다. 주거용 프록시와 스텔스 브라우저는 이러한 모든 위험을 줄여줍니다.
차단되지 않고 스크래핑하는 최선의 방법은 무엇인가요?
가장 신뢰할 수 있는 접근 방식은 주거용 프록시 회전, 현실적인 요청 헤더, 무작위 타이밍 지연, 스텔스 플러그인이 적용된 헤드리스 브라우저를 결합하는 것입니다. 생산 규모 스크래핑의 경우 Bright Data의 Web Unlocker와 같은 관리형 솔루션이 IP 회전, TLS 지문 관리, CAPTCHA 해결, 브라우저 렌더링을 단일 API 호출로 통합하여 자동으로 처리합니다.
웹 스크래핑은 합법인가요?
공개적으로 접근 가능한 데이터를 스크래핑하는 것은 대부분의 관할권에서 일반적으로 합법적이며, 특히 비개인적·비저작권 데이터의 경우 더욱 그렇습니다. 항상 대상 사이트의 robots.txt 및 이용약관을 확인하세요. 개인 데이터 스크래핑은 GDPR, CCPA 및 유사 법률에 따라 제한될 수 있습니다. 미국에서는 hiQ v. LinkedIn 판결을 통해 공개 데이터 스크래핑이 컴퓨터 사기 및 남용 방지법(Computer Fraud and Abuse Act)을 위반하지 않는다는 점이 확인되었습니다.
TLS 지문 인식이란 무엇인가요?
TLS 지문 인식은 HTTPS 핸드셰이크 과정에서 사용되는 암호화 모음(cipher suite), TLS 버전, 확장 기능의 고유한 조합을 분석하여 클라이언트 유형(브라우저, 봇, 스크립트)을 식별합니다. 봇 방지 시스템은 Python의 requests 라이브러리와 같은 알려진 스크래핑 도구를 차단하기 위해 JA3 및 JA4 해시를 사용합니다. 핵심 함의: TLS 스택이 Chrome이 아닌 OpenSSL처럼 보인다면, 아무리 완벽하게 현실적인 HTTP 헤더도 소용없습니다.
주거용 프록시가 데이터센터 프록시보다 더 효과적인 이유는 무엇인가요?
주거용 프록시는 실제 ISP 할당 IP 주소를 통해 트래픽을 라우팅합니다. 안티봇 시스템은 모든 유입 IP의 ASN(자율 시스템 번호)을 확인합니다. 데이터센터 IP는 AWS, GCP 등 잘 알려진 ASN에 속하며, 보안 수준이 높은 사이트에서는 기본적으로 차단됩니다. 반면 주거용 IP는 Comcast나 BT 같은 ISP에 속하므로 네트워크 계층에서 실제 사용자 트래픽과 구분하기 어렵습니다. 성능 차이에 대한 자세한 분석은 데이터센터 vs. 주거용 프록시 비교 자료를 참조하세요.