Kiedy Twój scraper nagle dostaje CAPTCHA od DataDome
Każdy inżynier scrapingu zna ten moment: Twój skrypt działał perfekcyjnie przez tygodnie, a potem nagle — na każdej stronie — pojawia się wyzwanie CAPTCHA, którego nie da się rozwiązać programowo. To DataDome. Jedna z najbardziej zaawansowanych platform ochrony przed botami na rynku, chroniąca setki dużych witryn — od wydawców newsowych po platformy e-commerce i bilety.
Zrozumienie, jak DataDome detection działa pod maską, jest kluczowe, jeśli chcesz, by Twoja legalna automatyzacja — monitorowanie cen, audyt SEO, badania bezpieczeństwa — działała niezawodnie. Ten artykuł rozkłada stos detekcji DataDome na czynniki pierwsze i pokazuje, jak residential proxies + odpowiednia konfiguracja przeglądarki pozwalają przejść czysto.
Stos detekcji DataDome — jak działa pod maską
DataDome nie polega na jednym sygnale. To system wielowarstwowy, który koreluje dziesiątki sygnałów w czasie rzeczywistym. Każda warstwa dodaje punktacji ryzyka; gdy suma przekroczy próg, ruch jest blokowany lub kierowany na CAPTCHA. Poniżej rozkładamy cztery główne warstwy.
Reputacja IP i analiza ASN
Pierwsza warstwa to najszybsza i najtańsza heurystyka: skąd przychodzi ruch? DataDome korzysta z komercyjnych baz danych IP (np. IP2Location, MaxMind) oraz własnej telemetrii, by sklasyfikować każde IP do jednej z kategorii:
- Datacenter — IP z zakresów przypisanych do dostawców chmurowych (AWS, Azure, OVH, Hetzner). Natychmiastowa flaga wysokiego ryzyka.
- Residential — IP przypisane do ISP obsługujących gospodarstwa domowe. Niska punktacja ryzyka, o ile nie figuruje na listach znanych proxy.
- Mobile — IP z sieci komórkowych (carrier-grade NAT). Najniższa punktacja ryzyka — DataDome traktuje ruch mobilny jako najbardziej „ludzki".
- Known-proxy lists — IP już zidentyfikowane jako wyjścia proxy/VPN. Wysoka punktacja niezależnie od klasy.
ASN analysis dodaje drugi wymiar: DataDome wie, że ASN przypisany do OVH SAS prawie nigdy nie generuje organicznego ruchu konsumentów na stronach e-commerce. Gęstość żądań z danego ASN na jednostkę czasu jest kolejnym sygnałem — jeśli z jednego /24 datacenter przychodzi 10 000 żądań na minutę, to nie są ludzie.
Kluczowe: DataDome agresywnie flaguje zakresy datacenter. Jeśli Twój scraper działa z IP AWS lub OVH, jesteś na najgorszym możliwym startowej pozycji.
Fingerprinting TLS — JA3 i JA4
Tu wchodzimy w techniczny detal, który większość scraperów ignoruje. Kiedy Twój klient nawiązuje połączenie TLS z serwerem chronionym DataDome, sam handshake jest analizowany zanim jakikolwiek HTTP zostanie wysłany.
JA3 to hash MD5 tworzony z: wersji TLS, zestawu szyfrów (cipher suites), listy rozszerzeń, listy grup elliptic-curve i formatów sygnatur. Różne klienty TLS mają różne „kolejki" szyfrów — i ta kolejność jest unikalnym identyfikatorem.
Na przykład:
- Chrome 125 na Windows:
771,4865-4866-4867...0x0304,0x0303→ określony hash JA3 - Python
requestsz domyślnymurllib3: zupełnie inna kolejność, inny hash curlz OpenSSL 3.x: jeszcze inna kolejność
JA4 to nowsza specyfikacja (2023), która dodaje więcej pól: ALPN values, liczba rozszerzeń, SNI presence. JA4 rozróżnia np. Chrome od Edge, które w JA3 mogły mieć podobny hash.
DataDome utrzymuje bazę „znanych" JA3/JA4 dla legalnych przeglądarek. Jeśli Twój hash nie pasuje do żadnej znanej przeglądarki — lub pasuje do znanego narzędzia automatycznego (headless Chrome bez flag, stary Python) — dostajesz punktację ryzyka.
Krytyczne konsekwencje:
requests.get()z Pythona ma JA3 kompletnie inny niż jakakolwiek przeglądarka — flaga natychmiast.- Headless Chrome bez modyfikacji ma charakterystyczny JA3 (brak niektórych rozszerzeń), który DataDome zna.
- Nawet
curlz określonym cipher suite może być odróżniony od Chrome.
Fingerprinting przeglądarki — canvas, WebGL, audio, navigator
Po przejściu TLS, DataDome uruchamia JavaScript, który zbiera dziesiątki sygnałów z przeglądarki:
Canvas fingerprinting: DataDome rysuje ukryty canvas z określonym tekstem i gradientami, potem odczytuje toDataURL(). Wynik różni się między GPU, sterownikami, systemem operacyjnym i przeglądarką. Headless Chrome na serwerze bez GPU daje powtarzalny, „pusty" wynik — natychmiastowa flaga.
WebGL fingerprinting: Odczytuje RENDERER i VENDOR z WebGL context. Headless Chrome raportuje Google SwiftShader lub Mesa — sygnał, że nie ma prawdziwego GPU.
Audio fingerprinting: Używa OfflineAudioContext do wygenerowania sygnału audio i pomiaru różnic w floating-point. Różnice między sprzętem są subtelne, ale powtarzalne. Brak różnic = środowisko bez sprzętowej karty dźwiękowej.
Navigator properties: navigator.webdriver (ustawiony na true w headless Chrome), navigator.plugins (pusty w headless), navigator.languages, navigator.hardwareConcurrency, navigator.platform. Każda niespójność — np. platform: Win32 ale languages: ["en-US"] z IP we Francji — dodaje punktacji.
DataDome koreluje te sygnały. Pojedyncza anomalia może nie wywołać blokady, ale canvas bez GPU + WebGL SwiftShader + webdriver=true to pewny ban.
Sygnnały behawioralne — dynamika myszy, scroll, timing
Najbardziej zaawansowana warstwa. DataDome analizuje jak użytkownik wchodzi w interakcję ze stroną:
- Mouse dynamics: Prędkość, przyspieszenie, zakręty. Ludzka mysz ma charakterystyczny „jitter" i krzywe Béziera. Bot porusza się po liniach prostych z stałą prędkością lub w ogóle nie generuje zdarzeń myszy.
- Scroll patterns: Ludzie scrollują nieregularnie — zatrzymują się, cofają, skrolują z różną prędkością. Boty skrolują natychmiast na dół lub w ogóle nie scrollują.
- Timing: Interwał między żądaniami. Człowiek czyta stronę przez 3-15 sekund przed kliknięciem. Bot wysyła żądania co 200ms z precyzyjnym interwałem.
- Touch events: Na mobile — sygnały dotykowe, rozmiar punktu styku, gesty. Brak touch events na mobile IP = silna flaga.
DataDome buduje model behawioralny w czasie rzeczywistym. Nawet jeśli Twój TLS i fingerprint przeglądarki są czyste, brak jakichkolwiek zdarzeń myszy w ciągu pierwszych 5 sekund na stronie podnosi punktację ryzyka.
Ciasteczko datadome i przepływ wyzwania CAPTCHA
Gdy wielowarstwowa analiza zdecyduje, że ruch jest podejrzany, DataDome uruchamia przepływ wyzwania:
- Pierwsze żądanie — DataDome jeszcze nie ma sygnałów behawioralnych, więc polega na IP + TLS + podstawowym JS. Jeśli punktacja jest wysoka, serwer zwraca 302 redirect do strony wyzwania.
- Strona wyzwania — ładuje JavaScript, który zbiera pełny fingerprint przeglądarki i sygnały behawioralne. Może wyświetlić CAPTCHA (reCAPTCHA, hCaptcha, lub własne DataDome CAPTCHA).
- Udane rozwiązanie — DataDome ustawia ciasteczko
datadomez określonym TTL (zwykle 24h). To ciasteczko jest szyfrowane i zawiera ocenę ryzyka. - Kolejne żądania — ciasteczko
datadomejest wysyłane z każdym żądaniem. Jeśli jest ważne i ma niską ocenę ryzyka, ruch przechodzi bez wyzwania.
Kluczowe implikacje:
- Ciasteczko
datadomejest powiązane z IP i fingerprintem, na którym zostało wydytowane. Zmiana IP bez zmiany ciasteczka — lub odwrotnie — może wywołać ponowne wyzwanie. - Ciasteczko ma TTL. Po wygaśnięciu, proces zaczyna się od nowa.
- Rozwiązywanie CAPTCHA przez solvery jest etycznie problematyczne i często wykrywane przez DataDome (analiza czasu rozwiązania, wzorców kliknięć).
Dlaczego residential i mobile proxies są kluczowe
Wracamy do warstwy IP — bo to ona decyduje o pierwszym wrażeniu DataDome. Poniżej porównanie trzech klas proxy pod kątem detekcji DataDome:
| Czynnik detekcji | Datacenter proxy | Residential proxy | Mobile proxy |
|---|---|---|---|
| Reputacja IP | Krytycznie niska — znane zakresy chmurowe | Wysoka — IP z ISP konsumenckich | Najwyższa — IP z sieci komórkowych |
| ASN analysis | ASN chmurowy — natychmiastowa flaga | ASN domowy — normalny ruch | ASN mobilny — najbardziej „ludzki" |
| Gęstość ruchu z /24 | Ekstremalna — tysiące botów na /24 | Niska — normalna dystrybucja | Bardzo niska — CGNAT, naturalna rotacja |
| Pojemność JA3/JA4 | Wysokie ryzyko — ruch z datacenter + nietypowy TLS | Średnie — IP OK, TLS nadal ważne | Niskie — IP i ASN kompensują anomalia TLS |
| Cena | Najniższa | Średnia | Najwyższa |
| Rekomendacja DataDome | Nie używać | Standardowy wybór | Dla najtrudniejszych celów |
Residential proxies to sweet spot: IP z prawdziwych ISP, rozsądna cena, i DataDome nie flaguje ich domyślnie. Mobile proxies są najlepsze dla najtrudniejszych celów (bilety, limited drops), ale kosztują więcej.
Geo-dopasowanie to kolejny kluczowy czynnik. Jeśli Twoje IP jest z Niemiec, ale navigator.language to en-US i timezone to America/New_York — DataDome widzi niespójność. Zawsze dopasowuj proxy, locale, timezone i Accept-Language do tego samego regionu.
Legalna automatyzacja — jak przejść czysto przez DataDome
Teraz łączymy wszystko w praktyczny setup. Cel: ruch, który DataDome widzi jako „prawdopodobnie ludzki" — bo pochodzi z residential IP, ma spójny fingerprint przeglądarki i generuje naturalne sygnały behawioralne.
Niewmodyfikowana przeglądarka z Playwright Stealth
Najważniejsza zasada: używaj prawdziwej przeglądarki, nie biblioteki HTTP. Playwright z odpowiednimi flagami i skryptami stealth to minimum.
from playwright.sync_api import sync_playwright
PROXY = {
"server": "http://gate.proxyhat.com:8080",
"username": "user-country-FR",
"password": "YOUR_PASSWORD"
}
with sync_playwright() as p:
browser = p.chromium.launch(
proxy=PROXY,
headless=True,
args=[
"--disable-blink-features=AutomationControlled",
"--disable-features=IsolateOrigins,site-per-process"
]
)
context = browser.new_context(
viewport={"width": 1920, "height": 1080},
locale="fr-FR",
timezone_id="Europe/Paris",
user_agent=(
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/125.0.0.0 Safari/537.36"
)
)
# Stealth: usunięcie flag webdriver i śladów automatyzacji
context.add_init_script("""
Object.defineProperty(navigator, 'webdriver', {get: () => undefined});
// Usunięcie Chrome DevTools Protocol markers
delete window.cdc_adoQpoasnfa76pfcZLmcfl_Array;
delete window.cdc_adoQpoasnfa76pfcZLmcfl_Promise;
delete window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol;
// Naprawa plugins i mimeTypes
Object.defineProperty(navigator, 'plugins', {
get: () => [1, 2, 3, 4, 5]
});
Object.defineProperty(navigator, 'languages', {
get: () => ['fr-FR', 'fr', 'en-US', 'en']
});
""")
page = context.new_page()
page.goto("https://example-datadome-site.com",
wait_until="domcontentloaded")
page.wait_for_timeout(3000) # ludzkie opóźnienie — „czytanie"
content = page.content()
print(f"Długość strony: {len(content)}")
browser.close()Kluczowe elementy:
- Residential proxy z Francji (
user-country-FR) — IP z francuskiego ISP. - Spójne locale:
fr-FR, timezoneEurope/Paris,Accept-Language: fr-FR. - Stealth init script — usuwa
navigator.webdriver, naprawia plugins i languages. - Opóźnienie 3 sekundy — symuluje czas „czytania" strony.
Residential proxy dopasowany geograficznie — test curl
Szybki test czy Twoje residential proxy jest akceptowane przez DataDome — bez przeglądarki, tylko weryfikacja IP:
# Test residential proxy z Niemiec — weryfikacja IP
# Uwaga: curl bez przeglądarki NIE przejdzie pełnej detekcji DataDome
# Ten test sprawdza tylko warstwę IP i podstawowe nagłówki
curl -x http://user-country-DE-city-berlin:YOUR_PASSWORD@gate.proxyhat.com:8080 \
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" \
-H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8" \
-H "Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7" \
-H "Accept-Encoding: gzip, deflate, br" \
-H "Sec-Ch-Ua: \"Google Chrome\";v=\"125\", \"Chromium\";v=\"125\", \"Not.A/Brand\";v=\"24\"" \
-H "Sec-Ch-Ua-Mobile: ?0" \
-H "Sec-Ch-Ua-Platform: \"Windows\"" \
-H "Sec-Fetch-Dest: document" \
-H "Sec-Fetch-Mode: navigate" \
-H "Sec-Fetch-Site: none" \
https://example-datadome-site.comTen test nie przejdzie pełnej detekcji DataDome — curl ma zupełnie inny JA3 niż Chrome. Ale potwierdzi, czy Twoje residential IP nie jest na liście znanych proxy. Jeśli nawet na tym etapie dostajesz CAPTCHA — IP jest zflagowane.
Interakcje w ludzkim tempie — Node.js z Playwright
Pełny setup z symulacją behawioralną — to jest to, co faktycznie przechodzi przez DataDome:
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
proxy: {
server: 'http://gate.proxyhat.com:8080',
username: 'user-country-DE-city-berlin',
password: 'YOUR_PASSWORD'
},
headless: true,
args: [
'--disable-blink-features=AutomationControlled',
'--disable-features=IsolateOrigins,site-per-process'
]
});
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 },
locale: 'de-DE',
timezoneId: 'Europe/Berlin',
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36'
});
// Stealth patches
await context.addInitScript(() => {
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5] });
Object.defineProperty(navigator, 'languages', {
get: () => ['de-DE', 'de', 'en-US', 'en']
});
});
const page = await context.newPage();
// Symulacja ludzkiego zachowania PRZED nawigacją
await page.mouse.move(200, 150, { steps: 15 });
await page.waitForTimeout(800);
await page.mouse.move(600, 400, { steps: 25 });
await page.waitForTimeout(1200);
// Nawigacja z referer
await page.goto('https://example-datadome-site.com', {
waitUntil: 'domcontentloaded',
referer: 'https://www.google.de/search?q=example'
});
// „Czytanie" strony — scroll z przerwami
await page.waitForTimeout(2500);
await page.mouse.wheel(0, 350);
await page.waitForTimeout(1800);
await page.mouse.wheel(0, 500);
await page.waitForTimeout(2200);
await page.mouse.move(800, 600, { steps: 20 });
// Ekstrakcja danych
const results = await page.$$eval('.product-card', cards =>
cards.map(card => ({
title: card.querySelector('h2')?.textContent?.trim(),
price: card.querySelector('.price')?.textContent?.trim()
}))
);
console.log(`Znaleziono ${results.length} produktów`);
console.log(results.slice(0, 3));
await browser.close();
})();Kluczowe elementy behawioralne:
- Ruchy myszy z
steps— generują krzywe Béziera, nie linie proste. - Scroll z przerwami — DataDome mierzy interwały między scroll events.
- Opóźnienia — losowe, w zakresie 800-2500ms, nie stałe 1000ms.
- Referer z Google — naturalny wzorzec nawigacji.
Sticky sessions — utrzymanie ciasteczka datadome
Ciasteczko datadome jest powiązane z IP. Jeśli używasz rotacji per-request, każde żądanie to nowy „użytkownik" bez ciasteczka — co oznacza ponowne wyzwania. Używaj sticky sessions, by utrzymać to samo IP przez całą sesję:
# Sticky session — to samo IP przez 30 minut
# Format: user-session-{identyfikator}
PROXY_URL="http://user-country-FR-session-mySession01:YOUR_PASSWORD@gate.proxyhat.com:8080"
# W Playwright:
proxy = {
"server": "http://gate.proxyhat.com:8080",
"username": "user-country-FR-session-mySession01",
"password": "YOUR_PASSWORD"
}Sticky session gwarantuje, że wszystkie żądania w ramach jednej sesji wychodzą z tego samego IP — więc ciasteczko datadome pozostaje ważne.
Ramy etyczne — dlaczego legalny dostęp ma sens
DataDome istnieje z powodu realnego problemu: boty skalpelowe masowo kupią bilety, skrapiają treści do shadow-sites, i przeprowadzają credential stuffing. To jest nadużycie, i ochrona przed nim jest uzasadniona.
Legalna automatyzacja to inna kategoria:
- Monitorowanie cen — Twoja firma potrzebuje danych o konkurencji, które są publicznie dostępne.
- Audyt SEO — sprawdzanie, jak Twoje strony rankują w różnych lokalizacjach.
- Badania bezpieczeństwa — authorized pentesting z wyraźną zgodą właściciela.
- Zbieranie danych do AI — publicznie dostępne treści do treningu modeli, z poszanowaniem robots.txt.
Etyczne zasady, których warto przestrzegać:
- Przestrzegaj robots.txt — jeśli strona wyraźnie zabrania scrapingu konkretnej sekcji, nie scrapuj jej.
- Stosuj rate limiting — nie więcej niż 1-2 żądania na sekundę per domena. To jest tempo, które nie obciąża serwerów.
- Nie używaj CAPTCHA solverów — jeśli DataDome pokazuje CAPTCHA, to znaczy, że Twój setup jest zły lub że strona nie chce automatyzacji. Rozwiązywanie CAPTCHA przez solvery to omijanie wyraźnej woli właściciela.
- Posiadaj legalny powód — security research, price monitoring własnych produktów, SERP tracking dla własnych domen.
- GDPR/CCPA — nie scrapuj danych osobowych bez podstawy prawnej.
Jeśli przestrzegasz tych zasad, Twoja automatyzacja jest legalna — a odpowiedni setup techniczny (residential proxy + stealth browser) po prostu zapewnia, że jest traktowana sprawiedliwie przez system detekcji.
Kiedy DataDome oznacza „użyj oficjalnego API"
Nie każdy chroniony DataDome site powinien być scrapowany. Niektórzy wydawcy i platformy celowo nie oferują API, ale ich warunki użytkowania wyraźnie zabraniają automatyzacji. Inni oferują API, ale jest drogie lub ograniczone.
Kiedy rozważyć oficjalne API zamiast scrapingu:
- Major news publishers — wielu wydawców (np. Le Monde, FAZ) ma API dla deweloperów. Jeśli istnieje, użyj go — to tańsze i stabilniejsze niż walka z DataDome.
- Platformy e-commerce z API — Amazon Product Advertising API, eBay API. Oczywiście, jeśli potrzebujesz danych z konkurencji, API może nie wystarczyć.
- Gdy CAPTCHA pojawia się mimo poprawnego setupu — to sygnał, że strona aktywnie nie chce automatyzacji. Przemyśl, czy Twój use case jest uzasadniony.
Z drugiej strony, wiele use cases nie ma alternatywy API:
- SERP tracking w różnych lokalizacjach — Google nie oferuje oficjalnego API z geo-targetowaniem.
- Monitorowanie cen konkurencji — konkurenci nie udostępniają API.
- Security research — authorized pentesting wymaga testowania z zewnątrz.
W tych przypadkach, residential proxies + poprawny setup to jedyna droga. Ale zawsze z poszanowaniem rate limitów i intencji właściciela strony.
Więcej o zastosowaniach scrapingu znajdziesz na naszej stronie use cases, a o SERP tracking — na stronie SERP tracking.
Kluczowe wnioski
DataDome detection jest wielowarstwowe — IP + TLS + fingerprint + behawior. Pojedyncza poprawka nie wystarczy; potrzebujesz spójnego setupu na wszystkich warstwach.
Residential proxies to fundament — datacenter IP są natychmiast flagowane. Mobile proxies są najlepsze, ale droższe. Geo-dopasowanie IP → locale → timezone jest obowiązkowe.
Używaj prawdziwej przeglądarki — Playwright z stealth patches, nie
requestsanicurldo scrapingu DataDome-protected sites.Symuluj ludzkie zachowanie — ruchy myszy, scroll, losowe opóźnienia. Brak sygnałów behawioralnych = flaga nawet z czystym IP i fingerprintem.
Sticky sessions — utrzymuj ciasteczko
datadomena tym samym IP. Rotacja per-request oznacza niekończące się wyzwania.Etyka first — przestrzegaj robots.txt, rate limitów, nie używaj CAPTCHA solverów. Jeśli strona aktywnie Cię blokuje mimo poprawnego setupu, rozważ oficjalne API.
Gotowy do budowy stabilnego pipeline'u scrapingu z residential proxies? Sprawdź ceny ProxyHat i dostępne lokalizacje — i zacznij od residential planu dopasowanego do Twoich celów.






