경쟁자의 가격 모니터링, 상품 재고 파싱 또는 마켓플레이스에 광고를 자동으로 게시하는 일을 하고 있다면 차단을 경험했을 것입니다. Wildberries, Ozon, Yandex.Market 및 Avito의 API는 자동화를 방지하기 위해 적극적으로 보호되고 있습니다: 요청 수를 제한하고, IP 주소를 차단하며, CAPTCHA를 요구합니다. 이 가이드에서는 차단이 발생하는 이유와 차단 없이 몇 달 동안 안정적으로 작업할 수 있도록 파서를 설정하는 방법을 설명합니다.
마켓플레이스가 API에 대한 빈번한 요청을 차단하는 이유
마켓플레이스는 인프라 유지에 막대한 비용을 지출합니다 — 서버, 데이터베이스, CDN. 가격 파싱을 위해 분당 수천 개의 요청을 보내면 그들의 시스템에 추가적인 부하를 생성하게 됩니다. 그러나 차단의 주요 원인은 기술적이지 않고 비즈니스 지향적입니다.
차단의 주요 원인:
- 경쟁 데이터 보호. Wildberries와 Ozon은 경쟁자가 가격, 재고 및 인기 상품 정보를 쉽게 얻는 것을 원하지 않습니다. 이 데이터는 상업적 비밀입니다.
- 서버 부하 감소. 하나의 파서는 10,000명의 일반 구매자와 같은 수의 요청을 생성할 수 있습니다. 이는 호스팅 비용을 증가시킵니다.
- 조작 및 스팸 방지. 자동 시스템은 Avito에서 조회수, 리뷰를 조작하거나 광고를 대량으로 게시하는 데 사용됩니다.
- API 수익화. 일부 마켓플레이스는 제한이 있는 공식 유료 API를 제공합니다. 무료 파싱을 차단함으로써 접근 구매를 유도합니다.
예를 들어, 매시간 5,000개의 상품 가격을 모니터링하면 하루에 120,000개의 요청이 발생합니다. 하나의 IP 주소에서 이는 의심스러워 보이며, 마켓플레이스의 보호 시스템은 빠르게 접근을 차단할 것입니다.
Wildberries, Ozon 및 Avito가 사용하는 보호 방법
현대의 마켓플레이스는 파싱에 대한 다층 보호를 사용합니다. 이러한 메커니즘을 이해하면 차단 우회를 올바르게 설정하는 데 도움이 됩니다.
| 보호 방법 | 작동 방식 | 우회 방법 |
|---|---|---|
| 속도 제한 | 하나의 IP에서 요청 제한: 시간당 100-500 | 요청 간 지연 + IP 회전 |
| IP 블랙리스트 | 데이터 센터의 알려진 프록시 차단 | 주거용 프록시 사용 |
| User-Agent 검사 | 브라우저 User-Agent 없이 요청 차단 | 실제적인 헤더 설정 |
| JavaScript 검사 | 데이터를 얻기 위해 JS 코드를 실행해야 함 | 헤드리스 브라우저 사용 |
| CAPTCHA | 의심스러운 활동 시 강제 검사 | 요청 빈도 감소, CAPTCHA 해결 서비스 사용 |
| TLS 핑거프린팅 | TLS 매개변수로 자동화를 식별 | 올바른 핑거프린트를 가진 라이브러리 사용 |
| 행동 분석 | 클릭 속도, 마우스 움직임 패턴 분석 | 지연 랜덤화, 인간 행동 모방 |
Wildberries는 공격적인 보호를 사용합니다: 하나의 IP에서 시간당 약 200-300개의 요청 제한, User-Agent 검사 및 JavaScript 챌린지. 제한을 초과하면 HTTP 429 (Too Many Requests) 또는 403 (Forbidden) 응답을 받게 됩니다.
Ozon은 API를 통한 파싱에 대해 더 관대하지만 데이터 센터의 IP를 적극적으로 차단합니다. 그들은 IP 유형(데이터 센터 vs 주거용)을 식별하는 서비스를 사용하므로 일반 프록시는 종종 작동하지 않습니다.
Avito는 대량 광고 게시 및 연락처 파싱으로부터 API를 보호합니다. 여기서 지리적 연결이 중요합니다: 예를 들어 카잔에 광고를 게시하면 IP는 카잔에서 나와야 하며, 그렇지 않으면 검토가 게시를 차단합니다.
속도 제한: 요청 간 지연을 올바르게 설정하는 방법
속도 제한은 요청 속도를 인위적으로 제한하여 귀하의 활동이 일반 사용자의 행동처럼 보이게 하는 것입니다. 주요 규칙은: 느리지만 안정적으로 하는 것이 빠르고 차단되는 것보다 낫습니다.
인기 마켓플레이스를 위한 권장 설정:
Wildberries:
- 요청 간 지연: 2-5초 (랜덤화됨)
- 하나의 IP에서 최대 150-200개의 요청
- 100개의 요청 후 10-15분의 대기
- 200개의 요청 후 IP 회전
Ozon:
- 요청 간 지연: 1-3초
- 하나의 IP에서 최대 300-400개의 요청
- 주거용 프록시 사용 필수
- 300개의 요청 후 IP 회전
Avito:
- 요청 간 지연: 3-7초
- 시간당 최대 50-100개의 요청 (엄격한 제한)
- IP는 광고 도시와 일치해야 함
- 하나의 IP = 하나의 계정 (혼합하지 마십시오)
랜덤화된 지연 구현 방법: "정확히 3초"와 같은 고정 간격을 사용하지 마십시오 — 이는 봇처럼 보입니다. 무작위성을 추가하십시오: 2초에서 5초 사이. 대부분의 파서는 이를 설정을 통해 지원합니다.
예를 들어, Python의 requests 라이브러리를 사용하면 다음과 같이 보입니다:
import time
import random
import requests
def make_request(url, proxies):
response = requests.get(url, proxies=proxies)
# 2초에서 5초 사이의 랜덤 지연
delay = random.uniform(2.0, 5.0)
time.sleep(delay)
return response
# 사용 예시
proxy = {
'http': 'http://username:password@proxy.example.com:8000',
'https': 'http://username:password@proxy.example.com:8000'
}
for product_id in product_list:
url = f'https://card.wb.ru/cards/detail?nm={product_id}'
response = make_request(url, proxy)
# 데이터 처리...
중요한 점: 100-200개의 요청 후에는 긴 대기(10-20분)를 하거나 IP를 변경하십시오. 이는 상품을 살펴보는 사람의 행동을 모방합니다.
부하 분산을 위한 프록시 회전
올바른 지연이 있더라도 하나의 IP는 오랜 부하를 견딜 수 없습니다. 해결책은 프록시 회전입니다: 여러 IP 주소 간에 요청을 분산시키는 것입니다. 이는 마켓플레이스의 안정적인 파싱의 기초입니다.
마켓플레이스 파싱을 위한 프록시 유형:
| 프록시 유형 | 장점 | 단점 | 어떤 작업에 적합한가 |
|---|---|---|---|
| 데이터 센터 | 빠르고, 저렴하며, 안정적임 | 쉽게 식별되며, 종종 차단 목록에 있음 | Yandex.Market, 소규모 마켓플레이스 |
| 주거용 | 실제 주거 사용자의 IP, 차단 위험이 낮음 | 데이터 센터보다 비싸고 느림 | Wildberries, Ozon, Avito |
| 모바일 | 모바일 운영자의 IP, 최대한의 익명성 | 가장 비싸고, 속도가 변동적임 | Avito의 강력한 차단 우회 |
Wildberries 및 Ozon을 파싱할 때는 주거용 프록시를 사용하는 것이 좋습니다 — 이들은 실제 주거 사용자의 IP를 가지고 있어 마켓플레이스가 일반 구매자와 구별할 수 없습니다. 데이터 센터 프록시는 여기에 잘 작동하지 않습니다: Ozon과 Wildberries는 이러한 IP를 블랙리스트에 올립니다.
프록시 회전 전략:
- N 요청 후 회전. 100-300 요청 후 IP를 변경하십시오. 이는 효율성과 안전성 간의 최적의 균형입니다.
- 시간에 따른 회전. 30-60분마다 IP를 변경하십시오. 긴 파싱 세션에 적합합니다.
- 스티키 세션. 하나의 상품/카테고리에 대한 모든 요청에 하나의 IP를 사용한 후 변경하십시오. 이는 의심을 줄입니다.
- 지리적 연결. Avito의 경우 필수: 모스크바의 광고는 모스크바 IP를 통해, 카잔의 광고는 카잔 IP를 통해 파싱하십시오.
대부분의 주거용 프록시 제공자는 자동 회전을 제공합니다: 하나의 엔드포인트를 받고, IP는 설정된 빈도 또는 각 요청 후 자동으로 변경됩니다. 이는 파서 설정을 간소화합니다.
Python에서 프록시 풀 설정 예시:
import requests
import random
# 프록시 목록 (파일에서 로드 가능)
proxy_list = [
'http://user:pass@proxy1.example.com:8000',
'http://user:pass@proxy2.example.com:8000',
'http://user:pass@proxy3.example.com:8000',
# ... 추가 50-100 프록시
]
def get_random_proxy():
proxy = random.choice(proxy_list)
return {
'http': proxy,
'https': proxy
}
# 사용 예시
for product_id in product_list:
proxy = get_random_proxy() # 각 요청에 대해 랜덤 프록시
response = requests.get(url, proxies=proxy)
# 데이터 처리...
브라우저를 모방하기 위한 헤더 및 핑거프린트 설정
마켓플레이스는 IP 및 요청 빈도뿐만 아니라 HTTP 헤더도 분석합니다. 만약 귀하의 파서가 라이브러리의 기본 헤더(예: python-requests/2.28.0)로 요청을 보낸다면, 즉시 봇으로 식별됩니다.
브라우저를 모방하기 위한 필수 헤더:
headers = {
'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',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'ru-RU,ru;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',
'Cache-Control': 'max-age=0',
'Referer': 'https://www.google.com/'
}
중요한 점:
- User-Agent는 실제 브라우저와 일치해야 합니다. 최신 버전의 Chrome, Firefox, Safari를 사용하십시오. 100-200 요청마다 User-Agent를 변경하십시오.
- Accept-Language는 프록시의 지리적 위치와 일치해야 합니다. 러시아 IP를 사용하는 경우 ru-RU를 설정하고, 우크라이나 IP를 사용하는 경우 uk-UA를 설정하십시오.
- Referer는 사용자가 어디에서 왔는지를 보여줍니다. 첫 번째 요청에는 Google/Yandex를 사용하고, 이후 요청에는 마켓플레이스의 내부 페이지를 사용하십시오.
- Sec-Fetch-* 헤더는 현실감을 더합니다. 현대 브라우저는 이를 자동으로 전송합니다.
TLS 핑거프린팅: 고급 보호 시스템(Ozon, Wildberries)은 TLS 연결의 매개변수를 분석합니다: 암호 스위트의 순서, 확장, 프로토콜 버전. 표준 Python/Node.js 라이브러리는 브라우저와 다른 핑거프린트를 가지고 있습니다.
해결책은 전문 라이브러리를 사용하는 것입니다:
- curl-impersonate (Python) — Chrome/Firefox의 TLS 핑거프린트를 모방합니다.
- tls-client (Go, Python 바인딩) — 조정 가능한 TLS 핑거프린트.
- Playwright / Puppeteer — 실제 TLS를 가진 헤드리스 브라우저.
대부분의 마켓플레이스 파싱 작업에는 올바른 HTTP 헤더와 주거용 프록시가 충분합니다. TLS 핑거프린팅은 가장 안전한 API 작업 시에만 중요합니다.
API vs 웹 스크래핑: 파싱에 더 안전한 것은 무엇인가
마켓플레이스는 데이터를 얻는 두 가지 방법이 있습니다: 공식 API와 HTML 페이지 파싱(웹 스크래핑). 안정적인 작업을 위해 어떤 것을 선택해야 할까요?
| 매개변수 | 공식 API | 웹 스크래핑 |
|---|---|---|
| 합법성 | ✅ 허용됨, 문서화됨 | ⚠️ 회색 영역, ToS를 위반할 수 있음 |
| 안정성 | ✅ 안정적인 데이터 구조 | ❌ 사이트 재설계 시 깨짐 |
| 제한 | ⚠️ 엄격한 공식 제한 | ⚠️ 비공식적이지만 보호가 있음 |
| 데이터 접근 | ⚠️ 모든 데이터에 접근할 수 없음 | ✅ 모든 공개 데이터 |
| 속도 | ✅ 빠른 JSON 응답 | ❌ HTML로 인해 느림 |
| 비용 | ⚠️ 종종 유료 | ✅ 무료 (프록시만 필요) |
선택에 대한 권장 사항:
- 공식 API를 사용하십시오: 소량의 데이터(하루 10,000개 이하)가 필요하고, 접근 비용을 지불할 준비가 되어 있으며, 합법성과 안정성이 중요합니다.
- 웹 스크래핑을 사용하십시오: 대량의 데이터가 필요하고, 공식 API가 필요한 정보를 제공하지 않으며(예: 경쟁자 가격), 예산이 제한적입니다.
하이브리드 접근: 많은 전문 파서는 두 가지 방법을 조합합니다. 예를 들어, API를 통해 상품 목록을 얻고(빠르고 합법적), 가격 및 재고에 대한 자세한 정보는 HTML 페이지에서 파싱합니다(더 많은 데이터).
마켓플레이스의 내부 API: 공식 API 외에도 마켓플레이스는 웹사이트 작업을 위한 내부 API를 사용합니다. 예를 들어, Wildberries는 https://card.wb.ru/cards/detail를 통해 상품 데이터를 로드합니다. 이러한 엔드포인트는 문서화되어 있지 않지만 HTML 파싱보다 더 빠르게 작동합니다. 단점은 예고 없이 변경될 수 있다는 것입니다.
인기 있는 파서 및 도구 설정
대부분의 판매자 및 마케터는 마켓플레이스 파싱을 위한 준비된 도구를 사용합니다. 인기 있는 솔루션에서 프록시 및 제한을 올바르게 설정하는 방법을 살펴보겠습니다.
Scrapy 설정 (Python 프레임워크)
Scrapy는 웹 스크래핑을 위한 인기 있는 프레임워크입니다. 마켓플레이스와 작업하기 위해 settings.py에 다음을 추가하십시오:
# 요청 간 지연
DOWNLOAD_DELAY = 3 # 3초
RANDOMIZE_DOWNLOAD_DELAY = True # 0.5*DELAY에서 1.5*DELAY까지 랜덤화
# 동시 요청 제한
CONCURRENT_REQUESTS = 8
CONCURRENT_REQUESTS_PER_DOMAIN = 2
# 프록시 설정 (미들웨어 rotating-proxies를 통해)
ROTATING_PROXY_LIST = [
'http://user:pass@proxy1.example.com:8000',
'http://user:pass@proxy2.example.com:8000',
# ... 프록시 목록
]
# User-Agent 회전
USER_AGENT_LIST = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Safari/537.36',
# ... User-Agent 목록
]
# 오류 발생 시 재시도
RETRY_TIMES = 3
RETRY_HTTP_CODES = [429, 500, 502, 503, 504]
Octoparse 설정 (코드 없는 비주얼 파서)
Octoparse는 프로그래밍 없이 파싱할 수 있는 인기 있는 도구입니다. 프록시 및 제한 설정:
- 작업 설정 → 고급 옵션을 엽니다.
- "네트워크" 섹션에서 "프록시 서버 사용"을 활성화합니다.
IP:PORT:USER:PASS형식으로 프록시 목록을 추가합니다.- 자동 회전을 위해 "각 요청에 대해 IP 회전"을 활성화합니다.
- "속도" 섹션에서 "느림" 또는 "사용자 정의"를 설정하고 3-5초의 지연을 설정합니다.
- 인간 행동을 모방하기 위해 "랜덤 지연"을 활성화합니다.
Selenium 설정 (브라우저 자동화)
Selenium은 실제 브라우저를 제어하므로 많은 보호를 우회할 수 있습니다. 프록시와 함께 설정하는 예시:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
import random
# 프록시와 함께 Chrome 설정
chrome_options = Options()
chrome_options.add_argument('--proxy-server=http://user:pass@proxy.example.com:8000')
chrome_options.add_argument('--disable-blink-features=AutomationControlled')
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=chrome_options)
# WebDriver 숨기기
driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
# 지연을 두고 파싱
urls = ['https://www.wildberries.ru/catalog/...', ...]
for url in urls:
driver.get(url)
# 3-7초의 랜덤 지연
time.sleep(random.uniform(3, 7))
# 읽기 모방을 위한 스크롤
driver.execute_script("window.scrollTo(0, document.body.scrollHeight/2);")
time.sleep(random.uniform(1, 3))
# 데이터 파싱
# ...
마켓플레이스 파싱을 위한 준비된 서비스
파서를 직접 설정하고 싶지 않다면 전문 서비스를 사용하십시오:
- Mpstats.io — Wildberries 및 Ozon 분석, 가격 및 판매 자동 모니터링
- SellerFox — 마켓플레이스에서 경쟁자 모니터링, 재고 추적
- Moneyplace — Avito 파싱, 광고 자동 게시
- Parsehub — 마켓플레이스를 포함한 모든 사이트를 위한 비주얼 파서
이러한 서비스는 이미 프록시, 제한 및 보호 우회를 설정했으므로 귀하는 무엇을 파싱할지 지정하기만 하면 됩니다. 단점은 월 구독료가 2000₽부터 시작한다는 것입니다.
차단 모니터링 및 자동 반응
올바른 설정이 있더라도 차단이 발생할 수 있습니다: 마켓플레이스는 보호를 업데이트하고, 프록시는 차단 목록에 오르며, 제한이 변경됩니다. 문제를 추적하고 자동으로 반응하는 것이 중요합니다.
모니터링해야 할 차단 징후:
- HTTP 429 (Too Many Requests) — 요청 제한 초과, 대기 또는 IP 변경 필요
- HTTP 403 (Forbidden) — IP 차단, 즉각적인 프록시 회전 필요
- HTTP 503 (Service Unavailable) — 일시적인 과부하 또는 DDoS 방지
- 응답에서 CAPTCHA — 자동화가 감지됨, 활동 감소 필요
- 빈 응답 또는 메인 페이지로 리디렉션 — 부드러운 차단
- 응답 시간 급증 — 서버 측에서 속도 제한 가능성
차단에 대한 자동 반응 (Python 예시):
import requests
import time
from datetime import datetime
class SmartParser:
def __init__(self, proxy_list):
self.proxy_list = proxy_list
self.current_proxy_index = 0
self.request_count = 0
self.blocked_proxies = set()
def get_next_proxy(self):
# 차단된 프록시 건너뛰기
while self.current_proxy_index in self.blocked_proxies:
self.current_proxy_index = (self.current_proxy_index + 1) % len(self.proxy_list)
proxy = self.proxy_list[self.current_proxy_index]
return {'http': proxy, 'https': proxy}
def rotate_proxy(self):
self.current_proxy_index = (self.current_proxy_index + 1) % len(self.proxy_list)
self.request_count = 0
def make_request(self, url):
max_retries = 3
for attempt in range(max_retries):
try:
proxy = self.get_next_proxy()
response = requests.get(url, proxies=proxy, timeout=10)
# 차단 확인
if response.status_code == 429:
print(f"[{datetime.now()}] 속도 제한! 60초 대기...")
time.sleep(60)
self.rotate_proxy()
continue
elif response.status_code == 403:
print(f"[{datetime.now()}] IP 차단됨! 프록시 회전 중...")
self.blocked_proxies.add(self.current_proxy_index)
self.rotate_proxy()
continue
elif response.status_code == 503:
print(f"[{datetime.now()}] 서버 과부하. 120초 대기...")
time.sleep(120)
continue
# 성공적인 요청
self.request_count += 1
# 200 요청 후 회전
if self.request_count >= 200:
self.rotate_proxy()
time.sleep(10) # 회전 후 대기
return response
except requests.exceptions.Timeout:
print(f"[{datetime.now()}] 타임아웃. 시도 {attempt + 1}/{max_retries}")
time.sleep(5)
return None # 모든 시도 소진
로깅 및 알림: 중요한 이벤트에 대한 알림을 설정하십시오. 예를 들어, 다음과 같은 경우 Telegram에 메시지를 보내십시오:
- 풀의 30% 이상의 프록시가 차단됨
- 성공적인 요청 비율이 80% 이하로 떨어짐
- 파서가 30분 이상 데이터를 받지 못함
- 응답에서 CAPTCHA 발견
모니터링할 메트릭:
- 성공률 — 성공적인 요청 비율 (90% 초과해야 함)
- 평균 응답 시간 — 평균 응답 시간 (증가는 문제를 나타낼 수 있음)
- 시간당 요청 수 — 각 프록시의 시간당 요청 수
- 프록시 건강 — 풀에서 작동하는 프록시 비율
- 차단 비율 — 차단 빈도 (5% 미만이어야 함)
메트릭 시각화를 위해 대시보드를 사용하십시오: Grafana, Datadog 또는 API를 통해 자동으로 업데이트되는 간단한 Google Sheets.
결론
마켓플레이스 파싱 시 차단은 장애물이 아니라 올바른 도구 설정으로 해결할 수 있는 과제입니다. 차단 없이 안정적으로 작업하기 위한 핵심 사항은 다음과 같습니다:
- Wildberries, Ozon 및 Avito에는 주거용 프록시를 사용하십시오 — 데이터 센터 프록시는 여기에 작동하지 않습니다.
- 요청 간 랜덤화된 지연을 2-5초로 설정하십시오.
- 150-300 요청 후 또는 30-60분마다 IP를 회전하십시오.
- 현재 User-Agent를 사용하여 현실적인 HTTP 헤더를 설정하십시오.
- 차단을 모니터링하고 자동으로 반응하십시오.
- Avito의 경우 광고 도시와 IP의 지리적 연결이 필수입니다.
올바르게 설정된 파서와 품질 좋은 프록시는 차단 없이 수개월 동안 작동할 수 있으며, 매일 수만 개의 상품을 수집할 수 있습니다. 중요한 것은 속도를 추구하기보다는 일반 사용자의 행동을 모방하는 것입니다.
Wildberries, Ozon 또는 Avito를 정기적으로 파싱할 계획이라면 주거용 프록시와 자동 회전을 사용하는 것이 좋습니다 — 이는 최대한의 안정성과 최소한의 차단 위험을 보장합니다. 모바일 IP가 필요한 작업(예: Avito의 강력한 차단 우회)에는 러시아 운영자의 모바일 프록시가 적합합니다.