마켓플레이스 파싱, 경쟁사 가격 모니터링 또는 웹사이트 데이터 수집을 하고 있다면 다음과 같은 문제를 알고 있을 것입니다: 웹사이트가 IP 주소를 차단하거나, 캡차를 요구하거나, 빈 페이지를 반환합니다. 차단율(차단된 요청의 비율)은 70-90%에 달할 수 있어 파싱이 불가능해집니다. 이 글에서는 차단율을 5-10%까지 낮추고 안정적으로 데이터를 수집하는 데 도움이 되는 구체적인 방법을 살펴보겠습니다.
기술적 솔루션(프록시 로테이션, HTTP 헤더, 핑거프린팅)과 행동 패턴(지연, 사용자 동작 모방) 모두를 다룰 것입니다. 모든 방법은 Wildberries, Ozon, Avito 및 해외 플랫폼 파싱에서 실제로 검증되었습니다.
웹사이트가 파서를 차단하는 이유: 주요 트리거
보호 방법을 분석하기 전에 웹사이트가 자동화된 트래픽을 어떻게 감지하는지 이해하는 것이 중요합니다. 현대적인 안티봇 시스템(Cloudflare, Akamai, DataDome, Imperva)은 각 요청의 수십 가지 매개변수를 분석합니다. 다음은 주요 차단 트리거입니다:
네트워크 수준 트리거:
- 하나의 IP 주소에서 너무 많은 요청(예: 분당 100개 이상의 요청)
- 알려진 데이터센터 범위의 IP(AWS, Google Cloud, Hetzner)
- 지리적 불일치: 러시아 IP가 영어 버전 사이트를 요청
- IP 주소에 대한 역방향 DNS 레코드 부재
HTTP 수준 트리거:
- HTTP 헤더 누락 또는 잘못된 헤더(User-Agent, Accept-Language, Referer)
- 헤더 순서가 브라우저 표준과 다름
- TLS/SSL 버전이 선언된 브라우저와 일치하지 않음
- 쿠키 부재 또는 잘못된 사용
브라우저 수준 트리거(JavaScript):
- JavaScript 실행 부재(단순 HTTP 클라이언트 사용 시)
- 브라우저 핑거프린팅: Canvas, WebGL, AudioContext, 설치된 폰트
- 마우스 움직임, 스크롤, 클릭 부재
- 브라우저 창 크기(헤드리스 브라우저는 종종 비표준 크기를 가짐)
- 자동화 존재: navigator.webdriver, window.chrome 속성
행동 트리거:
- 페이지 간 너무 빠른 탐색(1초 미만)
- 요청 간 동일한 간격(예: 정확히 2초마다)
- 건너뛰기 없이 순차적 페이지 탐색(1, 2, 3, 4...)
- 일반적인 사용자 동작 부재: 검색, 필터, 이미지 보기
예를 들어, Wildberries를 파싱할 때 일반적인 실수는 하나의 IP에서 0.5초마다 요청을 보내는 것입니다. Cloudflare 안티봇 시스템은 즉시 패턴을 감지하고 24시간 동안 IP를 차단합니다. 실제 사용자는 상품 카드를 보는 데 5-15초를 소비하고, 페이지를 스크롤하며, 이미지를 클릭합니다.
프록시 로테이션: IP 주소를 올바르게 변경하는 방법
프록시 사용은 차단율을 낮추는 기본 방법입니다. 하지만 단순히 프록시를 구매하는 것이 아니라 로테이션을 올바르게 설정하는 것이 중요합니다. 다음은 검증된 전략입니다:
파싱을 위한 프록시 유형 선택
| 프록시 유형 | 차단율 | 속도 | 사용 시기 |
|---|---|---|---|
| 데이터센터 프록시 | 높음 (40-60%) | 매우 빠름 | 보호 기능이 없는 단순 사이트, 대규모 IP 풀을 사용한 대량 파싱 |
| 주거용 프록시 | 낮음 (5-15%) | 보통 | 마켓플레이스(Wildberries, Ozon), Cloudflare가 있는 사이트, 소셜 네트워크 |
| 모바일 프록시 | 매우 낮음 (2-8%) | 느림 | 공격적인 보호 기능이 있는 사이트, 모바일 앱 버전 |
마켓플레이스(Wildberries, Ozon, Avito) 파싱에는 주거용 프록시를 권장합니다 — 실제 가정 사용자의 IP를 가지고 있어 일반 트래픽과 구별하기 어렵습니다. 데이터센터 프록시는 보호 기능이 약한 사이트나 대량의 데이터에서 최대 속도가 필요할 때 적합합니다.
IP 주소 로테이션 전략
전략 1: 시간 기반 로테이션
5-10분마다 IP를 변경하세요. 이것이 최적의 균형입니다: 빈번한 변경으로 의심을 일으키지 않을 만큼 충분히 길지만, 하나의 IP에 요청 기록이 누적되지 않을 만큼 충분히 자주 변경됩니다.
예시: 요청 간 3초 간격으로 1000개 상품 카탈로그를 파싱할 때, 하나의 IP는 약 100개의 요청 동안 활성화되고 그 후 변경됩니다.
전략 2: 요청 수 기반 로테이션
50-150개 요청 후 IP를 변경하세요. 이는 하나의 주소에 의심스러운 활동이 누적되는 것을 방지합니다. 무작위성을 추가하세요: 정확히 100개가 아니라 80-120개 사이.
예시: 무작위 요청 수(80-120) 후 풀에서 프록시 로테이션이 발생하도록 스크립트를 설정하세요.
전략 3: Sticky sessions (세션 프록시)
인증이 필요하거나 장바구니를 사용하는 사이트의 경우, sticky sessions를 사용하세요 — 세션 기간(10-30분) 동안 IP를 고정합니다. 이를 통해 쿠키를 유지하고 하나의 세션 내에서 IP를 변경할 때 의심을 일으키지 않습니다.
예시: Ozon의 개인 계정을 파싱할 때 로그인 및 15분 세션 내 모든 후속 요청에 하나의 IP를 사용하세요.
중요: 다른 작업에 동일한 IP를 사용하지 마세요. 한 사이트를 파싱하다가 IP가 차단되었다면, 다른 사이트에 즉시 사용하지 말고 24-48시간 기다리세요.
프록시 풀 크기
최소 풀 크기는 파싱 강도에 따라 다릅니다:
- 낮은 강도 (하루 최대 10,000개 요청): 10-20개 프록시
- 중간 강도 (하루 10,000 - 100,000개 요청): 50-100개 프록시
- 높은 강도 (하루 100,000개 이상 요청): 200개 이상 프록시 또는 자동 로테이션이 있는 주거용 프록시
각 요청마다 로테이션되는 주거용 프록시(rotating proxies)의 경우, 공급자가 수백만 개의 주소 풀에서 자동으로 새 IP를 제공하므로 풀 크기가 더 작을 수 있습니다.
User-Agent 및 HTTP 헤더: 실제 브라우저 모방
좋은 프록시를 사용하더라도 HTTP 헤더가 의심스러워 보이면 차단될 수 있습니다. 웹사이트는 User-Agent뿐만 아니라 헤더의 순서, 값 및 상호 일치 여부도 분석합니다.
올바른 User-Agent
모든 요청에 동일한 User-Agent를 사용하지 마세요. 인기 있는 브라우저 목록을 만들고 무작위로 선택하세요:
user_agents = [
# Windows의 Chrome
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
# macOS의 Chrome
"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",
# Windows의 Firefox
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
# macOS의 Safari
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Safari/605.1.15",
# Windows의 Edge
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0"
]
오류: 오래된 브라우저 버전(예: Chrome 80) 사용 — 즉시 의심을 일으킵니다. whatismybrowser.com에서 최신 버전을 추적하여 2-3개월마다 User-Agent 목록을 업데이트하세요.
전체 HTTP 헤더 세트
현대 브라우저는 15-20개의 헤더를 보냅니다. Chrome을 모방하기 위한 최소 필수 세트는 다음과 같습니다:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",
"Accept-Encoding": "gzip, deflate, br",
"DNT": "1",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"Cache-Control": "max-age=0",
"sec-ch-ua": '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"'
}
Sec-Fetch-* 및 sec-ch-ua-* 헤더에 주목하세요 — 이들은 Chrome의 새 버전에 나타났으며 이들의 부재는 자동화를 드러낼 수 있습니다.
헤더 순서가 중요합니다
브라우저는 특정 순서로 헤더를 보냅니다. 예를 들어, Chrome은 항상 Host를 먼저 배치하고, 그 다음 Connection, User-Agent 등을 배치합니다. Python 라이브러리 requests를 사용하면 순서가 알파벳순일 수 있어 자동화를 드러냅니다.
해결책: 헤더를 올바르게 형성하는 라이브러리(Python용 curl_cffi, Node.js용 got) 또는 실제 브라우저처럼 헤더를 생성하는 헤드리스 브라우저(Puppeteer, Playwright, Selenium)를 사용하세요.
요청 간 지연: 최적의 간격
차단율을 낮추는 가장 간단하지만 효과적인 방법 중 하나는 요청 간 올바른 지연입니다. 실제 사용자는 초당 10개의 페이지를 열 수 없으므로 너무 빠른 요청은 즉시 차단을 유발합니다.
고정 지연 대신 무작위 지연
고정 지연(예: 요청 간 정확히 2초)을 사용하지 마세요. 안티봇 시스템은 이러한 패턴을 쉽게 감지합니다. 무작위 간격을 사용하세요:
import random
import time
# 고정 지연 대신
time.sleep(2) # ❌ 나쁨
# 무작위 간격 사용
delay = random.uniform(2.5, 5.5) # ✅ 좋음
time.sleep(delay)
다양한 사이트에 권장되는 간격
| 사이트 유형 | 최소 지연 | 권장 지연 | 예시 |
|---|---|---|---|
| 보호 기능이 있는 마켓플레이스 | 3-5초 | 5-10초 | Wildberries, Ozon, Lamoda |
| 광고 게시판 | 2-4초 | 4-8초 | Avito, Yula, CIAN |
| 뉴스 사이트 | 1-2초 | 2-4초 | RBC, Kommersant, Vedomosti |
| 제한 없는 API | 0.5-1초 | 1-2초 | 오픈 API, RSS 피드 |
서버 응답 기반 적응형 지연
고급 접근 방식 — 서버 응답에 따라 지연을 동적으로 변경:
base_delay = 3.0 # 기본 지연
delay_multiplier = 1.0
response = requests.get(url, headers=headers, proxies=proxies)
# 캡차 또는 429를 받으면 — 지연 증가
if response.status_code == 429 or 'captcha' in response.text.lower():
delay_multiplier *= 1.5
print(f"보호 감지, 지연을 {base_delay * delay_multiplier}초로 증가")
# 모든 것이 정상이면 — 약간 가속 가능
elif response.status_code == 200:
delay_multiplier = max(1.0, delay_multiplier * 0.95)
time.sleep(random.uniform(base_delay * delay_multiplier, base_delay * delay_multiplier * 1.5))
이 접근 방식을 통해 보호가 감지되면 자동으로 속도를 늦추고 사이트가 공격적이지 않을 때 가속할 수 있습니다.
핑거프린팅 방지: Canvas, WebGL, 폰트
사이트가 JavaScript를 사용하여 확인하는 경우 단순한 HTTP 헤더만으로는 충분하지 않습니다. 현대적인 안티봇 시스템은 Canvas, WebGL, 설치된 폰트, 시간대, 화면 해상도 등 수십 가지 매개변수를 기반으로 브라우저 "지문"(fingerprint)을 생성합니다.
주요 핑거프린팅 매개변수
Canvas 핑거프린팅
사이트는 Canvas에 보이지 않는 이미지를 그리고 읽습니다. 다른 브라우저와 운영 체제는 이미지를 다르게 렌더링하여 고유한 지문을 생성합니다. 헤드리스 브라우저는 종종 동일한 Canvas를 생성하여 자동화를 드러냅니다.
WebGL 핑거프린팅
Canvas와 유사하지만 3D 렌더링을 사용합니다. 그래픽 카드, 드라이버, 지원되는 확장에 대한 정보를 읽습니다. 헤드리스 브라우저는 종종 실제 GPU 대신 소프트웨어 렌더링(SwiftShader)을 표시합니다.
설치된 폰트
JavaScript는 설치된 폰트 목록을 확인할 수 있습니다. 헤드리스 브라우저는 일반적으로 최소한의 시스템 폰트 세트를 가지고 있어 Microsoft Office, Adobe 및 기타 프로그램이 설치된 실제 사용자와 다릅니다.
Navigator 속성
navigator.webdriver, navigator.plugins, navigator.languages 속성은 자동화를 드러냅니다. 예를 들어, Selenium에서 navigator.webdriver === true이며, 이는 안티봇 시스템에 의해 즉시 감지됩니다.
핑거프린팅 우회 도구
핑거프린팅을 우회하려면 전문 도구를 사용하세요:
- Undetected ChromeDriver (Python) — 자동화 징후를 숨기는 수정된 Selenium 버전
- Puppeteer Stealth (Node.js) — fingerprint 매개변수를 대체하는 Puppeteer 플러그인
- Playwright with stealth — Puppeteer와 유사하지만 다양한 브라우저를 더 잘 지원
- 안티디텍트 브라우저 (Dolphin Anty, AdsPower, Multilogin) — 코드를 작성하고 싶지 않은 사람들을 위해 이러한 브라우저는 자동으로 fingerprint를 대체합니다
Python에서 undetected-chromedriver 사용 예:
import undetected_chromedriver as uc
# 감지 방지 기능이 있는 브라우저 생성
options = uc.ChromeOptions()
options.add_argument('--disable-blink-features=AutomationControlled')
driver = uc.Chrome(options=options)
driver.get('https://example.com')
# navigator.webdriver === undefined 확인
webdriver_status = driver.execute_script("return navigator.webdriver")
print(f"navigator.webdriver: {webdriver_status}") # None/undefined여야 함
쿠키 및 세션 관리
많은 사이트가 사용자 행동을 추적하기 위해 쿠키를 사용합니다. 올바른 쿠키 관리는 차단을 피하고 실제 사용자처럼 보이는 데 도움이 됩니다.
쿠키 저장 및 재사용
각 요청마다 새 세션을 생성하는 대신 쿠키를 저장하고 반복적으로 사용하세요. 이는 사이트로 돌아오는 실제 사용자의 행동을 모방합니다:
import requests
import pickle
session = requests.Session()
# 첫 방문 — 쿠키 받기
response = session.get('https://example.com')
# 쿠키를 파일에 저장
with open('cookies.pkl', 'wb') as f:
pickle.dump(session.cookies, f)
# 나중에 쿠키 로드
with open('cookies.pkl', 'rb') as f:
session.cookies.update(pickle.load(f))
# 이제 요청이 돌아온 사용자처럼 보임
response = session.get('https://example.com/catalog')
파싱 전 세션 워밍업
대상 페이지에서 즉시 파싱을 시작하지 마세요. 실제 사용자의 행동을 모방하세요:
- 사이트 메인 페이지 열기
- 2-5초 대기
- 카테고리 또는 섹션 페이지 열기
- 3-7초 대기
- 그 후에만 대상 페이지 파싱 시작
이는 쿠키에 활동 기록을 생성하고 차단 가능성을 줄입니다.
세션 쿠키 및 토큰 처리
일부 사이트는 첫 방문 시 고유 토큰을 생성하고 후속 요청에서 확인합니다. 예를 들어, Wildberries는 x-requested-with 헤더에 토큰을 사용합니다. 항상 첫 응답에서 이러한 토큰을 저장하고 후속 요청에서 보내세요.
JavaScript 렌더링: 필요한 경우
많은 현대 사이트가 JavaScript를 통해 콘텐츠를 로드합니다. 단순 HTTP 클라이언트(Python의 requests, Node.js의 axios)를 사용하면 빈 페이지나 스텁을 받게 됩니다. 이러한 경우 JavaScript 렌더링이 필요합니다.
JavaScript 렌더링이 필요한 경우
- 사이트가 React, Vue, Angular를 사용 — 초기 페이지 로드 후 콘텐츠가 로드됨
- AJAX/Fetch 요청을 통해 데이터가 로드됨
- 토큰 또는 쿠키 생성을 위해 JavaScript 실행이 필요한 사이트
- JS 코드 실행이 필요한 봇 방지 기능 존재(예: Cloudflare Challenge)
JavaScript 렌더링 도구
| 도구 | 언어 | 속도 | 보호 우회 |
|---|---|---|---|
| Selenium | Python, Java, C# | 느림 | 보통 (undetected-chromedriver 사용 시) |
| Puppeteer | Node.js | 보통 | 좋음 (puppeteer-extra-plugin-stealth 사용 시) |
| Playwright | Python, Node.js, Java | 빠름 | 우수함 |
| Splash | HTTP API | 보통 | 약함 |
대부분의 작업에는 Playwright를 권장합니다 — Selenium보다 빠르고, 보호를 더 잘 우회하며, 더 편리한 API를 가지고 있습니다.
대안: API 요청 가로채기
사이트가 데이터를 로드하는 데 사용하는 API 요청을 찾으면 JavaScript 렌더링을 피할 수 있는 경우가 많습니다. DevTools(F12) → Network 탭 → XHR/Fetch 필터를 열고 사이트가 보내는 요청을 확인하세요. 그런 다음 HTTP 클라이언트를 통해 이러한 요청을 직접 반복하세요.
예: Wildberries는 API https://catalog.wb.ru/catalog/...를 통해 상품 데이터를 로드합니다. 전체 페이지를 렌더링하는 대신 이 API를 직접 요청할 수 있으며, 이는 10-20배 더 빠릅니다.
캡차 우회: 자동 솔루션
올바른 프록시와 헤더를 사용하더라도 캡차에 직면할 수 있습니다. 해결을 위한 여러 접근 방식이 있습니다:
캡차 유형 및 해결 방법
reCAPTCHA v2 ("나는 로봇이 아닙니다" 체크박스)
인식 서비스를 통해 해결: 2Captcha, Anti-Captcha, CapMonster. 비용: 1000개 해결당 $1-3. 해결 시간: 10-30초.
reCAPTCHA v3 (보이지 않음, 점수 기반)
더 복잡합니다. 사용자 행동을 분석하고 0에서 1까지 점수를 부여합니다. 우회: 올바른 fingerprint를 가진 헤드리스 브라우저 사용 + 사용자 동작 모방(마우스 움직임, 클릭).
hCaptcha
reCAPTCHA의 유사품, 많은 사이트에서 사용됩니다. 동일한 인식 서비스를 통해 해결됩니다. 비용: 1000개 해결당 $0.5-2.
Cloudflare Challenge
브라우저를 확인하는 JavaScript 챌린지. 우회: 전문 라이브러리(Python용 cloudscraper, Node.js용 cloudflare-scraper) 또는 서비스(FlareSolverr) 사용.
캡차 인식 서비스 통합
Python에서 2Captcha 통합 예:
from twocaptcha import TwoCaptcha
solver = TwoCaptcha('YOUR_API_KEY')
try:
# reCAPTCHA v2 해결
result = solver.recaptcha(
sitekey='6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
url='https://example.com'
)
# 해결 토큰 받기
captcha_token = result['code']
# 토큰과 함께 양식 제출
response = requests.post('https://example.com/submit', data={
'g-recaptcha-response': captcha_token
})
except Exception as e:
print(f"캡차 해결 오류: {e}")
중요: 캡차 해결은 파싱 속도를 10-30배 늦추고 비용을 증가시킵니다. 다른 방법이 작동하지 않을 때만 사용하세요. 먼저 프록시, fingerprint 및 지연을 개선해 보세요.
속도 제한: 사이트 제한을 초과하지 않는 방법
많은 사이트에는 명시적 또는 암묵적 요청 수 제한이 있습니다. 이러한 제한을 초과하면 IP가 일시적 또는 영구적으로 차단됩니다.
사이트 제한 확인
서버 응답의 HTTP 헤더에 주목하세요:
X-RateLimit-Limit— 기간당 최대 요청 수X-RateLimit-Remaining— 남은 요청 수X-RateLimit-Reset— 제한이 재설정되는 시간(Unix 타임스탬프)Retry-After— 요청을 반복할 수 있는 시간(초)
상태 코드 429(Too Many Requests)를 받으면 제한 초과를 의미합니다. Retry-After 헤더를 읽고 다음 요청 전에 지정된 시간을 기다리세요.
속도 제한기 구현
요청 속도 제어 메커니즘을 만드세요:
import time
from collections import deque
class RateLimiter:
def __init__(self, max_requests, time_window):
self.max_requests = max_requests
self.time_window = time_window
self.requests = deque()
def wait_if_needed(self):
now = time.time()
# 시간 창을 벗어난 요청 제거
while self.requests and self.requests[0] < now - self.time_window:
self.requests.popleft()
# 제한에 도달하면 대기
if len(self.requests) >= self.max_requests:
sleep_time = self.time_window - (now - self.requests[0])
if sleep_time > 0:
print(f"속도 제한 도달, {sleep_time:.2f}초 대기")
time.sleep(sleep_time)
self.requests.popleft()
self.requests.append(time.time())
# 사용 예: 분당 최대 60개 요청
limiter = RateLimiter(max_requests=60, time_window=60)
for url in urls:
limiter.wait_if_needed()
response = requests.get(url)
메트릭 모니터링: 차단율 추적
파싱 효율성을 이해하려면 주요 메트릭을 추적해야 합니다:
추적할 주요 메트릭
- 차단율 — 차단된 요청의 비율 (4xx, 5xx 오류, 캡차, 빈 응답)
- 성공률 — 유효한 데이터를 받은 요청의 비율
- 평균 응답 시간 — 요청 속도 및 프록시 품질 이해
- IP당 요청 수 — 프록시 로테이션 효율성 확인
- 캡차 빈도 — 얼마나 자주 캡차를 해결해야 하는지
모니터링 구현
class ScraperMetrics:
def __init__(self):
self.total_requests = 0
self.successful_requests = 0
self.blocked_requests = 0
self.captcha_requests = 0
self.response_times = []
self.ip_usage = {}
def record_request(self, ip, response_time, status_code, has_captcha=False):
self.total_requests += 1
self.response_times.append(response_time)
# IP 사용 추적
self.ip_usage[ip] = self.ip_usage.get(ip, 0) + 1
if has_captcha:
self.captcha_requests += 1
if status_code == 200 and not has_captcha:
self.successful_requests += 1
else:
self.blocked_requests += 1
def get_stats(self):
ban_rate = (self.blocked_requests / self.total_requests * 100) if self.total_requests > 0 else 0
success_rate = (self.successful_requests / self.total_requests * 100) if self.total_requests > 0 else 0
avg_response_time = sum(self.response_times) / len(self.response_times) if self.response_times else 0
return {
'total_requests': self.total_requests,
'ban_rate': f"{ban_rate:.2f}%",
'success_rate': f"{success_rate:.2f}%",
'avg_response_time': f"{avg_response_time:.2f}s",
'captcha_rate': f"{(self.captcha_requests / self.total_requests * 100):.2f}%" if self.total_requests > 0 else "0%",
'unique_ips_used': len(self.ip_usage)
}
# 사용
metrics = ScraperMetrics()
for url in urls:
start_time = time.time()
response = requests.get(url, proxies=proxy)
response_time = time.time() - start_time
has_captcha = 'captcha' in response.text.lower()
metrics.record_request(proxy['http'], response_time, response.status_code, has_captcha)
print(metrics.get_stats())
파싱 도구 비교
작업에 적합한 도구를 선택하는 것이 중요합니다. 다음은 인기 있는 파싱 솔루션 비교입니다:
| 도구 | 장점 | 단점 | 최적 사용 사례 |
|---|---|---|---|
| Requests + BeautifulSoup | 빠름, 간단함, 리소스 소모 적음 | JS 렌더링 없음, 기본 보호 우회 어려움 | 정적 사이트, API, 보호 기능이 없는 사이트 |
| Scrapy | 고성능, 비동기, 내장 미들웨어 | 학습 곡선, JS 렌더링 없음 | 대규모 프로젝트, 여러 사이트 파싱 |
| Selenium | 완전한 브라우저 에뮬레이션, JS 지원 | 느림, 리소스 소모 많음, 쉽게 감지됨 | 복잡한 사용자 상호작용, 테스트 |
| Playwright | 빠름, 현대적 API, 좋은 보호 우회 | requests보다 리소스 소모 많음 | JS가 있는 현대 사이트, SPA |
| 상업용 API (ScraperAPI, Bright Data) | 프록시 관리 불필요, 자동 캡차 해결 | 비용, 제한된 사용자 정의 | 빠른 시작, 인프라 관리 불필요 |
결론
웹 스크래핑 시 차단율을 낮추는 것은 여러 방법의 조합입니다. 단일 "마법의 해결책"은 없습니다 — 성공은 프록시, 헤더, 지연, 핑거프린팅 및 행동 패턴의 올바른 조합에 달려 있습니다.
주요 권장 사항:
- 보호된 사이트(마켓플레이스, Cloudflare가 있는 사이트)에는 주거용 프록시 사용
- 5-10분마다 또는 50-150개 요청 후 IP 로테이션
- 최신 User-Agent 및 전체 HTTP 헤더 세트 사용
- 요청 간 무작위 지연 추가 (3-10초)
- JavaScript가 필요한 사이트에는 Playwright 또는 undetected-chromedriver 사용
- 차단율 및 기타 메트릭 모니터링, 전략 조정
- 가능한 경우 API 요청 가로채기 — 브라우저 렌더링보다 빠름
- 캡차 해결은 최후의 수단으로만 사용
이러한 방법을 올바르게 적용하면 차단율을 5-10%까지 낮추고 안정적으로 데이터를 수집할 수 있습니다. 작은 것부터 시작하세요: 좋은 프록시, 올바른 헤더, 적절한 지연 — 그리고 점차 더 고급 기술을 추가하세요.
파싱을 위한 고품질 프록시가 필요하신가요? ProxyCove는 주거용, 모바일 및 데이터센터 프록시를 제공하며 마켓플레이스 및 보호된 사이트 작업에 최적화되어 있습니다.