2026년 대규모 Shein 스크래핑: 프록시 기반 카탈로그·가격·재고 데이터 수집 가이드

2026년 대규모 Shein 스크래핑을 위한 실전 가이드. Akamai Bot Manager 우회, 내부 API 엔드포인트 활용, 주거용 프록시 회전으로 카탈로그·가격·재고 데이터를 안정적으로 수집하는 방법을 다룹니다.

Scraping Shein at Scale in 2026: A Practical Proxy Guide for Price Intelligence

2026년 대규모 Shein 스크래핑: API vs HTML 접근법

Shein은 전 세계 150개국 이상에서 운영되는 패션 이커머스 플랫폼으로, 매일 수만 개의 신상품이 등록됩니다. 가격 인텔리전스와 패션 시장 분석을 담당하는 분석가에게 2026년 대규모 Shein 스크래핑은 경쟁 모니터링의 핵심 과제가 되었습니다. 하지만 Shein의 강력한 안티봇 시스템 때문에 단순한 HTTP 요청으로는 데이터를 얻기 어렵습니다.

Shein 스크래핑의 첫 번째 결정은 렌더링된 HTML 파싱내부 API 엔드포인트 호출 중 어느 쪽을 선택할지입니다. 두 접근법은 각각 장단점이 명확합니다.

기준HTML 파싱내부 API 호출
데이터 품질CSS/XPath 셀렉터 의존, 구조 변경시 깨짐JSON 응답, 필드명 안정적
속도느림 (DOM 렌더링 필요)빠름 (3-5배 속도 향상)
안티봇 회피Akamai 전체 스크립트 로딩 필요쿠키/헤더만으로 충분
유지보수높음 (UI 변경시마다 수정)낮음 (API 구조 상대적 안정)

결론부터 말하면, 대규모 데이터 수집에는 내부 API 엔드포인트가 압도적으로 유리합니다. Shein은 /api/productInfo/api/products/list 같은 JSON API를 내부적으로 사용하며, 이 엔드포인트들은 렌더링된 HTML보다 안정적이고 빠릅니다. Shein 제품 스크래퍼를 구축할 때 API 우선 접근법이 필수적입니다.

Shein의 안티봇 스택: Akamai Bot Manager와 smdeviceid

Shein은 Akamai Bot Manager를 핵심 안티봇 솔루션으로 사용합니다. 이 시스템은 단순한 User-Agent 검사를 넘어 브라우저 지문(TLS fingerprint, Canvas API, WebGL 렌더링 등)과 행동 패턴을 종합적으로 분석합니다.

Akamai 봇 탐지의 핵심 요소는 다음과 같습니다:

  • _abck 쿠키: 브라우저 환경 검증 결과를 담은 쿠키. 유효한 _abck 쿠키가 없으면 403 또는 412 응답을 반환합니다.
  • bm_sz 쿠키: 봇 매니저 세션 식별자. _abck와 함께 검증에 사용됩니다.
  • sensor_data: 브라우저의 실제 동작을 시뮬레이션하는 JavaScript가 생성하는 원격 측정 데이터. 마우스 이동, 키보드 입력, 타이밍 정보 등을 포함합니다.
  • smdeviceid: 기기 식별 토큰. Shein이 추가로 사용하는 디바이스 핑거프린팅 쿠키로, _abck와 별개로 검증됩니다.

헤드리스 Chrome만으로는 차단됩니다. 일반적인 Selenium이나 Playwright 설정은 Akamai의 sensor_data 검증을 통과하지 못합니다. Akamai는 브라우저의 실제 렌더링 엔진 특성(TLS ClientHello, HTTP/2 프레임 순서, JavaScript 실행 환경)을 검사하므로, 단순히 헤드리스 브라우저를 사용하는 것만으로는 충분하지 않습니다. 2026년 기준으로 Akamai의 탐지 정확도는 99% 이상으로 보고되고 있습니다.

대신 curl_cffi와 같은 TLS 지문 매칭 라이브러리를 사용하면, 실제 Chrome의 TLS 핑거프린트를 모방하여 요청을 보낼 수 있습니다. 이 접근법은 헤드리스 브라우저의 오버헤드 없이도 Akamai의 기본 검증을 통과할 수 있습니다.

데이터 위치: productIntroData, gbProductDetail, 카테고리 피드

Shein 페이지에서 스크래핑할 수 있는 주요 데이터 위치는 세 가지입니다. Shein 가격 데이터를 정확히 수집하려면 각 데이터 소스의 구조를 이해해야 합니다.

1. 상품 상세 페이지의 JSON 블롭

상품 상세 페이지(/[category]-p-[goods_id].html)의 HTML 내부에는 두 개의 큰 JSON 블롭이 포함되어 있습니다:

  • productIntroData: 상품 설명, 이미지 URL, 사이즈 가이드, 색상 옵션 등
  • gbProductDetail: 가격 정보(retailPrice, salePrice), SKU 목록, 재고 상태, 할인 정보

이 데이터는 <script> 태그 내에 JSON 형태로 삽입되어 있으므로, 정규식이나 JSON 파서로 추출할 수 있습니다. 하지만 더 안정적인 방법은 API를 직접 호출하는 것입니다.

2. 내부 API 엔드포인트

Shein의 내부 API는 다음 패턴을 따릅니다:

# 상품 상세 정보
https://www.shein.com/api/productInfo?goods_id=12345678

# 카테고리 상품 리스트
https://www.shein.com/api/products/list?cat_id=1777&page=1&page_size=40

# 가격 및 재고 업데이트
https://www.shein.com/api/product/stock?goods_id=12345678

goods_id는 개별 상품 식별자이고, cat_id는 카테고리 식별자입니다. 이 값들은 Shein URL 구조에서 직접 추출할 수 있습니다. 예를 들어 https://www.shein.com/Women-Dresses-p-1777-cat-1727.html에서 cat_id=1727을 얻을 수 있습니다.

3. 카테고리 피드 엔드포인트

카테고리별 상품 목록을 가져오려면 /api/products/list 엔드포인트를 사용합니다. 응답에는 각 상품의 goods_id, goods_name, retailPrice, salePrice, stock 필드가 포함됩니다.

속도 제한과 프록시 회전 전략

Shein은 IP당 요청 빈도를 엄격하게 제한합니다. 실제 테스트 기준:

  • 동일 IP 기준: 약 30-50 requests/min 이후 412 응답 시작
  • 지속적 요청 시: 100 requests 이후 IP 차단(403)
  • 차단 해제 대기 시간: 30분~24시간 (IP 신뢰도에 따라)

이러한 속도 제한 때문에 주거용 프록시 회전이 필수적입니다. 특히 Shein은 지역별로 가격, 통화, 재고를 다르게 표시하므로, 지역 타겟팅이 중요합니다:

지역도메인통화가격 현지화재고 차이
USwww.shein.comUSD
DEeu.shein.comEUR
JPjp.shein.comJPY
KRkr.shein.comKRW

ProxyHat의 주거용 프록시를 사용하면 국가별 지역 타겟팅이 가능합니다. 미국 데이터가 필요하면 -country-US, 독일 데이터가 필요하면 -country-DE를 사용자명에 추가하세요. 지원 지역 전체 목록을 확인할 수 있습니다.

Python 실전 예제: curl_cffi + ProxyHat

다음은 curl_cffi를 사용하여 Shein의 내부 API를 호출하고, ProxyHat 주거용 프록시를 통해 라우팅하는 완전한 예제입니다. Shein 스크래핑을 위한 핵심 패턴을 보여줍니다:

from curl_cffi import requests
import json
import time

# ProxyHat 주거용 프록시 (미국 지역, 세션 고정)
PROXY_URL = "http://user-country-US-session-shein01:PASSWORD@gate.proxyhat.com:8080"

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": "application/json, text/plain, */*",
    "Accept-Language": "en-US,en;q=0.9",
    "Referer": "https://www.shein.com/",
    "Connection": "keep-alive",
}

def fetch_product(goods_id: str, max_retries: int = 3):
    url = f"https://www.shein.com/api/productInfo?goods_id={goods_id}"
    
    for attempt in range(max_retries):
        try:
            resp = requests.get(
                url,
                headers=HEADERS,
                proxies={"https": PROXY_URL, "http": PROXY_URL},
                impersonate="chrome120",
                timeout=15
            )
            
            if resp.status_code == 412:
                print(f"[412] _abck 갱신 필요, 재시도 {attempt + 1}")
                time.sleep(2 ** attempt)
                continue
            
            if resp.status_code == 200:
                return resp.json()
                
        except Exception as e:
            print(f"오류: {e}")
            time.sleep(2 ** attempt)
    
    return None

# 실행 예제
data = fetch_product("12345678")
if data:
    product = data.get("info", {}).get("products", [{}])[0] if data.get("info") else {}
    print(json.dumps({
        "goods_id": product.get("goods_id"),
        "retailPrice": product.get("retailPrice", {}).get("amount"),
        "salePrice": product.get("salePrice", {}).get("amount"),
        "stock": product.get("stock", "N/A"),
    }, indent=2))

위 코드의 출력 예시(실제 응답은 더 많은 필드를 포함합니다):

{
  "goods_id": "12345678",
  "retailPrice": "49.99",
  "salePrice": "29.99",
  "stock": "in_stock"
}

curl_cffi의 impersonate="chrome120" 옵션은 Chrome 120의 TLS 핑거프린트를 모방하여 Akamai의 기본 검증을 통과시킵니다. 자세한 설정은 ProxyHat 문서를 참조하세요.

페이지네이션, 세션 유지, 백오프 로직

페이지네이션 처리

카테고리 피드에서 모든 상품을 수집하려면 페이지네이션을 처리해야 합니다. Shein 스크래핑에서 페이지네이션은 가장 흔한 병목 지점입니다:

def scrape_category(cat_id: str, max_pages: int = 50):
    products = []
    for page in range(1, max_pages + 1):
        url = f"https://www.shein.com/api/products/list?cat_id={cat_id}&page={page}&page_size=40"
        resp = requests.get(url, headers=HEADERS,
                           proxies={"https": PROXY_URL},
                           impersonate="chrome120", timeout=15)
        if resp.status_code != 200:
            break
        data = resp.json()
        items = data.get("info", {}).get("products", [])
        if not items:
            break
        products.extend(items)
        time.sleep(1.5)  # 요청 간격
    return products

세션 고정으로 통화 일관성 유지

여러 페이지를 스크래핑할 때 IP가 바뀌면 통화와 가격이 변경될 수 있습니다. sticky session을 사용하면 동일 IP를 유지하여 통화 일관성을 확보할 수 있습니다:

# 세션 ID를 고정하면 동일 IP 유지
PROXY_URL = "http://user-country-US-session-shein01:PASSWORD@gate.proxyhat.com:8080"

# 카테고리별로 다른 세션 사용
PROXY_CAT_1777 = "http://user-country-US-session-cat1777:PASSWORD@gate.proxyhat.com:8080"
PROXY_CAT_2000 = "http://user-country-US-session-cat2000:PASSWORD@gate.proxyhat.com:8080"

카테고리별로 다른 세션 ID를 사용하면 IP 회전과 일관성의 균형을 맞출 수 있습니다. 예를 들어 session-cat1777, session-cat2000처럼 카테고리별 세션을 할당하세요.

412 / _abck 갱신 로직

412 응답을 받으면 _abck 쿠키를 갱신해야 합니다. 실용적인 접근법:

  1. 412 응답 시 해당 세션을 5분간 휴면
  2. 새 세션 ID로 프록시 회전 (새 IP 획득)
  3. 지수 백오프 적용 (1s → 2s → 4s → 8s)
  4. 최대 3회 재시도 후 해당 goods_id를 재시도 큐에 추가
import random

def fetch_with_backoff(url, session_id="shein01", max_retries=5):
    for attempt in range(max_retries):
        # 시도마다 새 세션 ID 생성하여 새 IP 획득
        sid = f"{session_id}-{attempt}-{random.randint(1000,9999)}"
        proxy = f"http://user-country-US-session-{sid}:PASSWORD@gate.proxyhat.com:8080"
        
        try:
            resp = requests.get(url, headers=HEADERS,
                              proxies={"https": proxy, "http": proxy},
                              impersonate="chrome120", timeout=15)
            if resp.status_code == 200:
                return resp.json()
            elif resp.status_code == 412:
                wait = 2 ** attempt + random.uniform(0, 1)
                time.sleep(wait)
            elif resp.status_code == 403:
                time.sleep(30)  # IP 차단, 긴 대기
        except Exception:
            time.sleep(2 ** attempt)
    return None

윤리와 이용약관: 공개 데이터만 수집

Shein 스크래핑은 공개된 상품 정보(가격, 재고, 설명, 이미지 URL) 수집에 국한해야 합니다. 다음 사항을 반드시 준수하세요:

  • 공개 데이터만: 로그인이 필요한 페이지, 결제 프로세스, 계정 정보는 수집하지 마세요.
  • robots.txt 준수: Shein의 robots.txt를 확인하고 허용된 경로만 스크래핑하세요.
  • 요청 속도 제한: 서버에 부하를 주지 않도록 적절한 간격(1-2초)을 유지하세요.
  • 개인정보 보호: 사용자 리뷰의 작성자 정보 등 개인 데이터는 GDPR에 따라 별도 동의가 필요합니다.
  • CFAA 주의: 미국 컴퓨터 사기 및 남용법(CFAA)은 무단 접근을 금지합니다. 공개 페이지 스크래핑은 일반적으로 허용되지만, 인증 우회는 위법입니다.

대안: 공식 제휴 피드: 대규모 상업용 데이터 수집이 목적이라면, Shein 제휴 프로그램을 통해 공식 데이터 피드에 접근하는 것이 더 안정적이고 법적으로 안전할 수 있습니다. 제휴 파트너는 API 액세스와 정기적인 데이터 업데이트를 제공받습니다.

프록시 가격 정보는 ProxyHat 요금제 페이지에서 확인할 수 있으며, 웹 스크래핑 사용 사례는 웹 스크래핑 사용 사례에서, SERP 추적 관련 내용은 SERP 추적 페이지에서 확인하세요.

핵심 요약

  • API 우선: HTML 파싱보다 /api/productInfo/api/products/list 엔드포인트를 사용하는 것이 3-5배 빠르고 안정적입니다.
  • TLS 매칭 필수: curl_cffi의 impersonate 옵션으로 Chrome TLS 핑거프린트를 모방하세요. 헤드리스 Chrome만으로는 Akamai를 통과하기 어렵습니다.
  • 주거용 프록시 + 지역 타겟팅: Shein은 지역별로 가격과 재고가 다르므로 -country-US 또는 -country-DE 지역 타겟팅이 필수입니다.
  • 세션 고정: 통화 일관성을 위해 카테고리별 sticky session을 사용하세요.
  • 윤리 준수: 공개 데이터만 수집하고, 서버 부하를 최소화하며, 필요시 공식 제휴 피드를 검토하세요.

시작할 준비가 되셨나요?

AI 필터링으로 148개국 이상에서 5천만 개 이상의 레지덴셜 IP에 액세스하세요.

가격 보기레지덴셜 프록시
← 블로그로 돌아가기