Skrapowanie Shein na dużą skalę w 2026: API vs parsowanie HTML
Skrapowanie Shein na dużą skalę w 2026 roku wymaga świadomej decyzji architektonicznej już na starcie: czy parsować wyrenderowany HTML, czy uderzać bezpośrednio w wewnętrzne endpointy JSON, które Shein wykorzystuje do ładowania danych produktów. Ta decyzja determinuje całą resztę implementacji — od stopnia skomplikowania kodu, przez zużycie proxy, aż po wskaźnik sukcesu.
Shein, jako jedna z największych platform e-commerce fashion na świecie z przychodem przekraczającym 30 miliardów dolarów w 2024 roku, nie udostępnia publicznego API do pobierania danych produktowych. Zamiast tego strona opiera się na wewnętrznych endpointach JSON, które zasilają frontend napisany w React. Te endpointy — takie jak /api/productInfo czy endpointy kategorii z parametrami goods_id i cat_id — zwracają ustrukturyzowane dane, które są znacznie łatwiejsze do przetworzenia niż HTML.
Parsowanie HTML jest kuszące, bo wydaje się prostsze: ładujesz stronę, wybierasz selektory CSS i wyciągasz dane. Problem polega na tym, że HTML Shein jest generowany dynamicznie, zawiera setki klas CSS generowanych automatycznie i zmienia się przy każdym deploymencie. Endpointy JSON są stabilniejsze, zwracają czyste struktury danych i zużywają mniej transferu — często 5-10x mniej niż pełna strona HTML.
Kluczowa decyzja: Endpointy JSON są wydajniejsze, stabilniejsze i łatwiejsze do mapowania na schemat bazy danych. HTML jest ostatecznością, gdy endpointy są niedostępne lub zablokowane.
Stack anti-bot Shein: Dlaczego headless Chrome nie wystarczy
Shein korzysta z Akamai Bot Manager — jednego z najbardziej zaawansowanych systemów ochrony anti-bot na rynku. To nie jest prosty rate-limiter. Akamai analizuje odcisk TLS, nagłówki HTTP, zachowanie JavaScript i telemetrię urządzenia w czasie rzeczywistym.
Ciasteczko _abck i sensor_data
Sercem ochrony Akamai jest ciasteczko _abck, które jest ustawiane przez skrypt JavaScript /_sec/.../akam/*/ i odświeżane na podstawie tzw. sensor_data — zaszyfrowanej telemetrii zawierającej informacje o środowisku przeglądarki: rozdzielczości ekranu, czcionkach, wtyczkach, zachowaniu myszy i klawiatury. Jeśli sensor_data nie zostanie poprawnie wygenerowana, ciasteczko _abck otrzyma flagę oznaczającą "zły" status, a kolejne żądania otrzymają kod HTTP 412 (Precondition Failed).
Dodatkowo Shein wykorzystuje token smdeviceid — identyfikator urządzenia przypisany do sesji przeglądarki, który jest sprawdzany przy każdym żądaniu API. Brak tego tokenu lub jego niespójność z innymi nagłówkami powoduje natychmiastowe zablokowanie.
Dlaczego headless Chrome dostaje blokadę
Standardowy headless Chrome (nawet z flagami --disable-blink-features=AutomationControlled) zostaje wykryty przez Akamai w ciągu kilku żądań. Powody:
- Odcisk TLS: Headless Chrome ma inny odcisk TLS niż prawdziwy Chrome, szczególnie w kolejności szyfrów i rozszerzeniach.
- Webdriver flag:
navigator.webdriveri inne właściwości DOM zdradzają automatyzację. - Brak interakcji: Akamai sprawdza, czy generowana jest realna telemetria myszy/klawiatury. Skrypt bez interakcji = bot.
- IP datacenter: Adresy IP z zakresów datacenter są natychmiast flagowane.
Zamiast walczyć z Akamai na poziomie przeglądarki, lepszym podejściem jest użycie bibliotek takich jak curl_cffi, które dopasowują odcisk TLS do prawdziwej przeglądarki, w połączeniu z rezydencyjnymi adresami IP. To eliminuje dwa z czterech problemów naraz.
Gdzie znajdują się dane: JSON blobs i endpointy API
Shein przechowuje dane produktów w kilku miejscach, które można wykorzystać do skrapowania:
1. Endpointy API produktów
Główny endpoint dla szczegółów produktu to wariacja /api/productInfo z parametrem goods_id. Odpowiedź zawiera pełne dane: cenę detaliczną, cenę promocyjną, stany magazynowe per SKU, atrybuty, rozmiary i kolory.
GET https://www.shein.com/api/productInfo?goods_id=12345678&country=US¤cy=USD
2. On-page JSON blobs
Na stronie produktu, w tagu <script>, znajdują się obiekty JSON takie jak productIntroData i gbProductDetail. Można je wyciągnąć za pomocą XPath:
//script[contains(text(), 'productIntroData')]/text()
3. Endpointy kategorii (feed produktów)
Listy produktów w kategoriach są ładowane przez endpointy z parametrami cat_id i paginacją page:
GET https://www.shein.com/Category-API?cat_id=2020&page=1&page_size=40&country=US
Każdy element w odpowiedzi zawiera goods_id, który można użyć do pobrania pełnych szczegółów przez endpoint produktu.
4. Pola SKU i inventory
W odpowiedzi API produktu, stany magazynowe znajdują się w strukturze productIntroData.detail.goods_stock lub w tablicy sku_list, gdzie każdy element zawiera sku_code, stock i salePrice.amount.
Rate limity i dlaczego rotacyjne proxy rezydencyjne są konieczne
Shein stosuje agresywne rate limiting per IP. Na podstawie testów empirycznych i donieszeń społeczności scrapingowej, orientacyjne progi wyglądają następująco:
| Typ IP | Próg rate limit | Czas blokady | Wskaźnik sukcesu |
|---|---|---|---|
| Datacenter | ~3 żądania | 24h+ (często permanentna) | <10% |
| Residential (bez rotacji) | ~50 żądań / 10 min | 1-6h | ~60% |
| Residential (rotacja per-request) | ~5-10 żądań / IP / min | Rzadko, jeśli tempo jest kontrolowane | ~85-95% |
| Mobile (rotacja) | ~15-20 żądań / IP / min | Bardzo rzadko | ~95%+ |
Kluczowym powodem, dla którego rotacja IP to konieczność, jest lokalizacja geograficzna. Shein dynamicznie dostosowuje ceny, waluty i dostępność produktów na podstawie kraju i regionu użytkownika. Produkt dostępny w USA może być niedostępny w Niemczech, a cena w EUR może różnić się od ceny w USD nie tylko kursem walutowym, ale też lokalną strategią cenową.
Dlatego każdy Shein product scraper musi wysyłać żądania z IP zlokalizowanych w docelowym kraju. Proxy rezydencyjne z geo-targetingiem — np. -country-US lub -country-DE — rozwiązują ten problem, symulując ruch od realnych użytkowników w danym regionie.
Sprawdź dostępne lokalizacje ProxyHat na stronie /locations, aby upewnić się, że docelowe kraje są wspierane.
Praktyczna implementacja: Python, curl_cffi i ProxyHat
Poniżej znajduje się kompletny przykład skrapowania danych produktu Shein z wykorzystaniem curl_cffi (dla dopasowania TLS) i ProxyHat jako bramy proxy. Biblioteka curl_cffi automatycznie emuluje odcisk TLS Chrome, co rozwiązuje problem wykrywania na poziomie TLS.
Najpierw zainstaluj zależności:
pip install curl_cffi
Teraz implementacja skrapera:
from curl_cffi import requests
import json
import time
# ProxyHat — proxy rezydencyjne z geo-targetingiem US
PROXY_URL = "http://user-country-US:pass@gate.proxyhat.com:8080"
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
"Accept": "application/json, text/plain, */*",
"Accept-Language": "en-US,en;q=0.9",
"Referer": "https://www.shein.com/",
"Origin": "https://www.shein.com",
}
def fetch_product(goods_id: str, country: str = "US"):
url = f"https://www.shein.com/api/productInfo?goods_id={goods_id}&country={country}"
proxies = {
"http": f"http://user-country-{country}:pass@gate.proxyhat.com:8080",
"https": f"http://user-country-{country}:pass@gate.proxyhat.com:8080",
}
resp = requests.get(
url,
headers=HEADERS,
proxies=proxies,
impersonate="chrome131",
timeout=15,
)
if resp.status_code == 412:
print(f"[!] 412 — _abck challenge. Backoff i retry.")
time.sleep(5)
return None
if resp.status_code != 200:
print(f"[!] HTTP {resp.status_code}")
return None
return resp.json()
def extract_product_fields(raw: dict):
"""Wyciąga kluczowe pola z odpowiedzi API."""
info = raw.get("info", {}).get("productIntroData", raw.get("info", {}))
return {
"goods_id": info.get("goods_id"),
"goods_name": info.get("goods_name"),
"retail_price": info.get("retailPrice", {}).get("amount"),
"sale_price": info.get("salePrice", {}).get("amount"),
"currency": info.get("salePrice", {}).get("currency"),
"stock": info.get("goods_stock"),
"sku_list": [
{
"sku_code": s.get("sku_code"),
"stock": s.get("stock"),
"price": s.get("salePrice", {}).get("amount"),
}
for s in info.get("sku_list", [])
],
}
# Przykład użycia
if __name__ == "__main__":
data = fetch_product("12345678", country="US")
if data:
product = extract_product_fields(data)
print(json.dumps(product, indent=2, ensure_ascii=False))
Przykładowa (skrócona) odpowiedź
{
"goods_id": "12345678",
"goods_name": "Solid Drop Shoulder Oversized Sweater",
"retail_price": "42.00",
"sale_price": "15.99",
"currency": "USD",
"stock": 2847,
"sku_list": [
{"sku_code": "SKU-A001", "stock": 312, "price": "15.99"},
{"sku_code": "SKU-A002", "stock": 0, "price": "15.99"},
{"sku_code": "SKU-A003", "stock": 128, "price": "15.99"}
]
}
Zauważ, że retail_price to cena referencyjna (przed obniżką), a sale_price to cena faktyczna. Pole stock na poziomie produktu to suma stanów wszystkich SKU. Poszczególne SKU mogą mieć stock: 0, co oznacza, że konkretny wariant rozmiaru/koloru jest wyprzedany.
Paginacja, sticky sessions i logika backoff
Paginacja katalogu
Do skanowania całego katalogu Shein musisz iterować przez strony kategorii. Każda strona zwraca do 40 produktów. Oto logika paginacji:
def scrape_category(cat_id: str, country: str = "US", max_pages: int = 50):
all_goods_ids = []
for page in range(1, max_pages + 1):
# Sticky session dla spójności walutowej
session_id = f"shein-{cat_id}-{country}"
proxy_url = f"http://user-country-{country}-session-{session_id}:pass@gate.proxyhat.com:8080"
url = f"https://www.shein.com/Category-API?cat_id={cat_id}&page={page}&page_size=40&country={country}"
resp = requests.get(
url,
headers=HEADERS,
proxies={"https": proxy_url},
impersonate="chrome131",
timeout=15,
)
if resp.status_code == 412:
print(f"[!] 412 na stronie {page}. Backoff 10s.")
time.sleep(10)
continue
if resp.status_code != 200:
print(f"[!] HTTP {resp.status_code} na stronie {page}")
break
data = resp.json()
items = data.get("info", {}).get("products", [])
if not items:
print(f"[*] Koniec katalogu na stronie {page}")
break
for item in items:
all_goods_ids.append(item.get("goods_id"))
print(f"[*] Strona {page}: {len(items)} produktów")
time.sleep(2) # Rate limit: ~5 req/min per IP
return all_goods_ids
Sticky sessions dla spójności walutowej
Kiedy skrapujesz produkty z określonego kraju, musisz utrzymywać ten sam adres IP przez całą sesję — w przeciwnym razie Shein może zwrócić ceny w różnych walutach, jeśli IP nagle zmieni geolokację. ProxyHat wspiera sticky sessions poprzez flagę -session- w nazwie użytkownika:
http://user-country-US-session-shein-batch-001:pass@gate.proxyhat.com:8080
Wszystkie żądania z tą samą nazwą sesji wychodzą z tego samego adresu IP, zapewniając spójność waluty i dostępności produktów przez całą sesję.
Logika backoff i odświeżanie _abck
Kod 412 oznacza, że Akamai wymaga odświeżenia ciasteczka _abck. Strategia postępowania:
- Pierwszy 412: Odczekaj 5 sekund i ponów żądanie. Akamai czasami ustawia poprawne
_abckpo pierwszym wyzwaniu. - Drugi 412: Zmień adres IP (nowa sesja proxy) i odczekaj 30 sekund.
- Trzeci 412: Odczekaj 5 minut i zmień geo-lokalizację proxy na inne miasto w tym samym kraju.
- Ciągłe 412: Zmień kraj lub zatrzymaj skrapowanie na 24h.
def fetch_with_backoff(goods_id: str, country: str, max_retries: int = 3):
for attempt in range(max_retries):
session_id = f"shein-{country}-{int(time.time())}"
proxy_url = f"http://user-country-{country}-session-{session_id}:pass@gate.proxyhat.com:8080"
resp = requests.get(
f"https://www.shein.com/api/productInfo?goods_id={goods_id}&country={country}",
headers=HEADERS,
proxies={"https": proxy_url},
impersonate="chrome131",
timeout=15,
)
if resp.status_code == 200:
return resp.json()
elif resp.status_code == 412:
wait = [5, 30, 300][attempt]
print(f"[!] 412, prób {attempt+1}/{max_retries}, czekam {wait}s")
time.sleep(wait)
else:
print(f"[!] HTTP {resp.status_code}")
time.sleep(10)
return None
Etyka, TOS i aspekty prawne
Skrapowanie Shein — jak każdej platformy e-commerce — wiąże się z kwestiami prawnymi i etycznymi. Oto kluczowe zasady, których należy przestrzegać:
1. Tylko publiczne dane produktowe
Skrapuj wyłącznie dane, które są publicznie dostępne bez logowania: ceny, opisy, zdjęcia produktów, stany magazynowe i kategorie. Nie skrapuj danych użytkowników, recenzji wymagających konta ani żadnych informacji z panelu konta.
2. CFAA i GDPR
W Stanach Zjednoczonych Computer Fraud and Abuse Act (CFAA) kriminalizuje "nieautoryzowany dostęp" do systemów komputerowych. Choć precedensy takie jak hiQ Labs v. LinkedIn sugerują, że skrapowanie publicznych danych jest legalne, omijanie systemów anti-bot może być interpretowane jako naruszenie CFAA. W Unii Europejskiej GDPR chroni dane osobowe — skrapowanie danych zawierających informacje osobowe (np. recenzje z imionami) bez podstawy prawnej jest nielegalne.
3. Brak dostępu do checkout i kont
Nie próbuj skrapować procesu checkout, danych kart płatniczych ani panelu konta. To jest jednoznacznie nielegalne i narusza TOS Shein.
4. Kiedy oficjalny feed afiliacyjny jest lepszy
Shein posiada program afiliacyjny z dostępem do feedów produktowych (często przez sieci takie jak CJ Affiliate lub ShareASale). Jeśli potrzebujesz danych do porównywarki cen lub analizy rynkowej, oficjalny feed:
- Jest legalny i zgodny z TOS
- Zawiera ustrukturyzowane dane XML/CSV
- Aktualizuje się codziennie lub co kilka godzin
- Nie wymaga proxy ani omijania anti-bot
Skrapowanie jest uzasadnione, gdy potrzebujesz danych w czasie rzeczywistym (np. co godzinę), feed afiliacyjny nie zawiera wymaganych pól (np. stanów magazynowych per SKU) lub potrzebujesz danych dla krajów niewspieranych przez feed.
Konfiguracja ProxyHat i zasoby
ProxyHat oferuje rezydencyjne, mobilne i datacenter proxy z geo-targetingiem na poziomie kraju i miasta. Dla skrapowania Shein rekomendujemy:
- Proxy rezydencyjne z rotacją per-request do skanowania katalogu.
- Sticky sessions (flaga
-session-) do pobierania szczegółów produktów z spójnością walutową. - Geo-targeting (flaga
-country-) dopasowany do docelowych rynków.
Sprawdź ceny ProxyHat oraz przypadki użycia web scraping, aby dobrać odpowiedni plan. Pełną dokumentację techniczną znajdziesz na docs.proxyhat.com. Jeśli skrapujesz również wyniki wyszukiwania, zobacz nasz przypadek użycia SERP tracking.
Kluczowe wnioski
- Wybierz endpointy JSON zamiast parsowania HTML — są stabilniejsze, wydajniejsze i łatwiejsze do mapowania.
- Akamai Bot Manager jest główną przeszkodą. Używaj
curl_cffizimpersonate="chrome131"do dopasowania TLS. - Rotacyjne proxy rezydencyjne z geo-targetingiem są konieczne — Shein lokalizuje ceny i dostępność per kraj.
- Sticky sessions zapewniają spójność walutową podczas pobierania szczegółów produktów.
- Logika backoff przy kodach 412 jest kluczowa — nie ponawiaj natychmiast, tylko odczekaj i zmień IP.
- Przestrzegaj TOS i prawa — skrapuj tylko publiczne dane produktowe, rozważ oficjalny feed afiliacyjny jako alternatywę.
Często zadawane pytania
Czym jest skrapowanie Shein na dużą skalę w 2026?
Skrapowanie Shein na dużą skalę w 2026 to proces automatycznego pobierania danych katalogu, cen i stanów magazynowych z platformy shein.com z wykorzystaniem rotacyjnych proxy rezydencyjnych i technik omijania systemów anti-bot takich jak Akamai Bot Manager. Wymaga geo-targetingu, ponieważ Shein lokalizuje ceny, waluty i dostępność produktów w zależności od kraju użytkownika.
Dlaczego skrapowanie Shein na dużą skalę w 2026 jest ważne dla użytkowników proxy?
Shein stosuje zaawansowane systemy anti-bot, które blokują standardowe skrapery i datacenter IP. Użytkownicy proxy potrzebują rezydencyjnych adresów IP z geo-targetingiem, aby symulować ruch z różnych lokalizacji, utrzymywać spójność walutową i unikać blokad. To sprawia, że skrapowanie Shein jest jednym z najbardziej wymagających przypadków użycia dla usług proxy.
Który typ proxy działa najlepiej do skrapowania Shein w 2026?
Rezydencyjne proxy z rotacją IP i geo-targetingiem działają najlepiej do skrapowania Shein. Adresy IP datacenter są szybko wykrywane i blokowane przez Akamai Bot Manager. Proxy mobilne są jeszcze bezpieczniejsze, ale droższe. Kluczowe jest użycie sticky sessions dla spójności walutowej oraz rotacji per-request dla skanowania katalogu.
Jak uniknąć blokad przy implementacji skrapowania Shein w 2026?
Aby uniknąć blokad, należy używać proxy rezydencyjnych z geo-targetingiem, dopasować odcisk TLS przeglądarki za pomocą bibliotek takich jak curl_cffi, implementować logikę backoff przy kodach 412, odświeżać ciasteczka _abck, utrzymywać sticky sessions dla spójności walutowej i ograniczyć tempo zapytań do około 5-10 zapytań na IP na minutę.






