Обхід DataDome

Як обійти DataDome за допомогою Python: повний посібник 2026 року

Короткий підсумок

  • Що таке DataDome насправді і чому його справді важко обійти
  • 5 рівнів виявлення, які DataDome використовує проти вашого скрапера
  • Техніки з акцентом на код: TLS impersonation, stealth browsers, ротація проксі, поведінкова мімікрія
  • Повна архітектурна діаграма Mermaid для конвеєра обходу
  • Коли побудова власного стеку перестає мати сенс

1. У чому саме полягає проблема з DataDome

Ви вже обходили ліміти запитів раніше. Цього разу все інакше — і це так.

DataDome — це не простий файрвол, який можна обійти підробкою заголовків. Це AI-рушій оцінювання в реальному часі, який використовують понад 1 200 компаній у всьому світі, зокрема великі європейські e-commerce-платформи, сайти з продажу квитків і маркетплейси (DataDome.co).

Обробляє три трильйони сигналів на день щоб визначити, чи ви людина.

Ваш чистий Python-вебскрапер зламається вже на першому запиті. Перш ніж зрозуміти, як це виправити, треба зрозуміти саму боротьбу.

2. Як DataDome насправді вас виявляє

DataDome не перемикає бінарний режим «бот чи ні». Він формує бал довіри у режимі реального часу через п’ять одночасних рівнів виявлення (Scrapfly, 2026).

Пропустіть один шар, і бал опуститься нижче порога. Тоді ви отримаєте 403, CAPTCHA зі слайдером або порожній HTML без жодних повідомлень.

П’ять рівнів, у порядку швидкості перевірки:

Рівень Що перевіряється Метод DataDome TLS-фінгерпринт Набір шифрів, порядок розширень, хеш JA3 Хешування JA3/JA4 під час handshake Репутація IP Тип ASN, історія зловживань, діапазони датацентрів Пошук в IP-базі в реальному часі Деталі HTTP Версія протоколу, порядок заголовків, відсутні поля Аналіз HTTP/1.1 проти HTTP/2 Браузерний фінгерпринт Canvas, WebGL, navigator.webdriver, плагіни, движок виконання JavaScript, поведінковий аналіз, криві руху миші, ритм прокрутки, навігаційний потік, ML-моделі за шаблонами сесій

Оцінка довіри не є статичною. Вона безперервно перераховується протягом вашої сесії. Вебскрапер, який проходить перші три перевірки, все одно може бути заблокований на 3-й сторінці, якщо його поведінка під час прокрутки виглядає роботизованою.

3. Виявлення блокування DataDome

Перш ніж будувати обхід, переконайтеся, що ви справді маєте справу з DataDome. Характерні ознаки однакові:

  • HTTP 403 Forbidden під час першого або ранніх запитів
  • datadome ключ у Set-Cookie заголовок відповіді
  • An x-datadome-cid поле в заголовках відповіді
  • Сторінка зі slider CAPTCHA завантажується замість вмісту сайту
  • Рядок dd з’являючись у тегу `script` в HTML заблокованої відповіді

Швидка перевірка за допомогою curl показує все:

curl -I https://www.target-site.com
# Look for: set-cookie: datadome=...
# Or:       x-datadome-cid: ...

Після підтвердження ви знаєте, з якими рівнями маєте справу. Тепер візьмімося за них по черзі.

4. Рівень 1 — TLS-фінгерпринтинг: Невидимий перший удар

Це найшвидша й найжорсткіша перевірка DataDome. Вона спрацьовує ще до того, як надійдуть ваші заголовки.

Коли Python’s requests Бібліотека підключається через HTTPS, а TLS-handshake розкриває JA3-хеш — відбиток порядку наборів шифрів, списку розширень і версії протоколу. JA3-хеш для requests/urllib3 зовсім не схоже на Chrome (DataDome Engineering, 2022).

DataDome веде базу відомих відбитків ботів. Ваш запит зіставляється за мілісекунди.

Виправлення: curl_cffi — бібліотека Python, яка обгортає curl-impersonate і відтворює точний TLS-handshake Chrome.

# pip install curl_cffi
from curl_cffi import requests
session = requests.Session(impersonate="chrome")
response = session.get("https://target-site.com")
print(response.status_code)  # Should be 200, not 403

The impersonate="chrome" параметр не просто імітує заголовок. Він змінює увесь TLS-handshake — порядок наборів шифрів, значення розширень, параметри кадрів HTTP/2 — щоб точно відповідати Chrome 131+.

Серед підтримуваних цілей для імітації є chromechrome131safarisafari_ios, і edge101. Бібліотека оновлює ці відбитки, коли браузери випускають нові версії.

Ця єдина зміна знімає значну частину блокувань DataDome. Але це лише перший шар.

5. Рівень 2 — HTTP-заголовки: найпомітніша ознака бота

Python за замовчуванням requests User-Agent — це python-requests/2.31.0. Кожен сайт, захищений DataDome, блокує це миттєво. Але User-Agent узагалі не є головною проблемою.

DataDome перевіряє повнота та порядок заголовків як пакет. Chrome надсилає 15+ структурованих заголовків у порядку, специфічному для браузера. Відсутні Sec-Fetch-Dest, надсилання заголовків у неправильній послідовності або наявність невідповідного Accept-Language порівняно з геолокацією проксі все це обвалює ваш trust score.

from curl_cffi import requests
CHROME_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": "text/html,application/xhtml+xml,application/xml;q=0.9,"
              "image/avif,image/webp,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br, zstd",
    "Sec-CH-UA": '"Not A(Brand";v="8", "Chromium";v="131", "Google Chrome";v="131"',
    "Sec-CH-UA-Mobile": "?0",
    "Sec-CH-UA-Platform": '"Windows"',
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-User": "?1",
    "Upgrade-Insecure-Requests": "1",
}
session = requests.Session(impersonate="chrome")
response = session.get("https://target-site.com", headers=CHROME_HEADERS)

Критичне правило геосумісності: якщо ваш проксі французький, ваш Accept-Language має бути fr-FR,fr;q=0.9. Німецька IP-адреса в парі з en-US мовний заголовок — це тривіальна невідповідність, яку моделі DataDome легко виявляють.

Також: більшість бібліотек для вебскрапінгу досі за замовчуванням використовують HTTP/1.1. DataDome це позначає. Сучасні сайти працюють на HTTP/2 або HTTP/3. Використання curl_cffi or httpx Увімкнення HTTP/2 розв’язує це автоматично.

6. Рівень 3 — репутація IP: основа Trust Score

DataDome зіставляє кожну IP-адресу, що підключається, з кількома базами даних про загрози в режимі реального часу. Вердикт для datacenter IP миттєвий і жорсткий.

Репутація IP-адреси становить, за оцінками, 25–30% від оцінки довіри. У вас можуть бути ідеальні заголовки та бездоганний TLS-відбиток, але вас усе одно заблокують, бо ваша IP-адреса належить AWS. us-east-1.

Три рівні IP і їхній вплив на довіру:

Datacenter IPs (AWS, GCP, DigitalOcean)  → Immediate negative score, pre-blocked ranges
Residential IPs (ISP-assigned, real homes) → High trust, harder to abuse at scale  
Mobile IPs (carrier-grade NAT)             → Highest trust, shared ranges hard to block

Ротація проксі з резидентськими або мобільними IP-адресами є обов’язковою для DataDome. Ось чиста реалізація:

from curl_cffi import requests
import random
RESIDENTIAL_PROXIES = [
    "http://user:[email protected]:8000",
    "http://user:[email protected]:8000",
    "http://user:[email protected]:8000",
]
def get_proxy() -> dict:
    proxy = random.choice(RESIDENTIAL_PROXIES)
    return {"http": проксі, "https": proxy}
session = requests.Session(impersonate="chrome")
response = session.get(
    "https://target-site.com",
    headers=CHROME_HEADERS,
    proxies=get_proxy(),
    timeout=15
)

⚠️ Постійні сесії мають значення: ніколи не ротуйте IP-адреси посеред сесії для багатокрокових потоків. Потік login → browse → checkout, який стрибає між IP-адресами посеред виконання, є величезним червоним прапорцем для поведінкового шару DataDome.

Використовуйте sticky-сесії для багатосторінкових потоків. Ротуйте лише на start нової незалежної сесії.

7. Рівень 4 — браузерний фінґерпринтинг: допит JavaScript

Для сайтів, що рендерять контент за допомогою JavaScript (а захищені DataDome сайти майже завжди так і роблять), вам потрібен справжній браузер. Але звичайні Playwright і Selenium одразу себе видають.

Стандартні headless-браузери всюди витікають бот-сигнали (Kameleo, 2025):

  • navigator.webdriver === true — жорстко закодований прапорець автоматизації
  • Відсутні плагіни (Chrome PDF ViewerGoogle Docs Offline)
  • Absent window.chrome.runtime object
  • програмне GPU-рендерення SwiftShader замість реального виводу GPU
  • Canvas/WebGL, що генерують трохи інші піксельні результати, ніж справжні браузери

Виправлення: playwright-stealth у поєднанні з ручним патчингом властивостей:

# pip install playwright playwright-stealth
import asyncio
from playwright.async_api import async_playwright
from playwright_stealth import stealth_async
async def stealth_scrape(url: str) -> str:
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=True,
            args=["--disable-blink-features=AutomationControlled"]
        )
        context = await browser.new_context(
            viewport={"width": 1920, "height": 1080},
            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"
            ),
            locale="en-US",
            timezone_id="America/New_York",
        )
        page = await context.new_page()
        # Apply stealth patches (200+ виправлення витоків)
        await stealth_async(page)
        # Additional manual patching for DataDome-специфічні перевірки
        await page.add_init_script("""
            Object.defineProperty(navigator, 'platform', {
                get: () => 'Win32'
            });
            Object.defineProperty(navigator, 'plugins', {
                get: () => [
                    { name: 'Chrome PDF Plugin' },
                    { name: 'Chrome PDF Viewer' },
                    { name: 'Native Client' }
                ]
            });
        """)
        await page.goto(url, wait_until="networkidle")
        content = await page.content()
        await browser.close()
        return content
html = asyncio.run(stealth_scrape("https://target-site.com"))

Для розробників, орієнтованих насамперед на Python, яким потрібен ще сильніший обхід виявлення, camoufox — спеціально пропатчена збірка Firefox — і undetected-chromedriver для Selenium варто тримати у своєму наборі інструментів.

8. Рівень 5 — поведінковий аналіз: найскладніший рівень

Пройти всі чотири попередні рівні все одно недостатньо для стабільного вебскрапінгу. ML-моделі DataDome вивчають how ви поводитеся протягом усієї сесії.

Сигнали, які відстежуються:

  • Рух миші: реальні користувачі використовують криві Безьє з природним прискоренням і джитером
  • Поведінка прокручування: нерівномірні ривки з паузами, а не лінійні прирости пікселів
  • Таймінг запиту: люди роблять паузи 2–15 секунд між діями, а не 50 мс
  • Потік навігації: реальні користувачі відвідують головну сторінку → категорію → товар, а не переходять одразу на сторінки за прямим посиланням
  • Прогрів сесії: going straight to a product URL is suspicious; browsing first is natural
import asyncio
import random
async def human_delay(min_s: float = 1.5, max_s: float = 4.0):
    """Randomized delay with realistic variance - not wild swings."""
    await asyncio.sleep(random.uniform(min_s, max_s))
async def scroll_naturally(page):
    """Scroll in bursts, pause between them, like a real reader."""
    chunks = random.randint(3, 6)
    for _ in range(chunks):
        scroll_px = random.randint(80, 250)
        await page.mouse.wheel(0, scroll_px)
        await asyncio.sleep(random.uniform(0.4, 1.3))
async def warm_up_session(page, base_url: str):
    """
    Visit homepage and browse naturally before hitting target.
    DataDome rewards sessions that 'feel' like real shopping journeys.
    """
    await page.goto(base_url, wait_until="domcontentloaded")
    await human_delay(2.0, 4.0)
    await scroll_naturally(page)
    await human_delay(1.5, 3.0)
    # Then navigate to your actual target

⚠️ Pitfall: Надто багато випадковості теж викликає підозру. Затримки 0,01–30 секунд виглядають як зламаний бот. Тримайте діапазони реалістичними: 1–4 секунди для читання сторінок, 0,3–1,5 секунди для фрагментів прокрутки.

9. CAPTCHA DataDome: коли виявлення коректно дає збій

Навіть якщо ви врахуєте всі п’ять рівнів, цільові ресурси з великим трафіком періодично створюватимуть для вас виклики. Система CAPTCHA DataDome переважно є слайдерна перевірка — це не прапорець і не сітка зображень. Вона вимірює фізику того, як ви перетягуєте повзунок.

Ваші варіанти, коли з’являється CAPTCHA:

Варіант A — сервіси розв'язання CAPTCHA (e.g. 2Captcha, CapSolver):

from twocaptcha import TwoCaptcha
solver = TwoCaptcha("YOUR_API_KEY")
result = solver.datadome(
    pageurl="https://target-site.com/blocked-page",
    captcha_url="https://geo.captcha-delivery.com/captcha/..."
)
token = result["code"]
# Inject the token back into the session cookie

Варіант B — профілактика важливіша за лікування: clean IPs + realistic behavior + proper fingerprints = fewer CAPTCHAs appearing in the first place. Solvers cost $1–3 per 1,000 CAPTCHAs and add 5–20 seconds each. At scale, prevention has a far better ROI.

10. Повна архітектура: діаграма Mermaid

Ось як усі п’ять шарів поєднуються в пайплайні обходу DataDome продакшн-рівня:

Натисніть Enter або клацніть, щоб переглянути зображення у повному розмірі

11. Усе разом: повний клас для обходу DataDome

import asyncio
import random
import time
from curl_cffi import requests as cffi_requests
from playwright.async_api import async_playwright
from playwright_stealth import stealth_async
PROXIES = [
    "http://user:[email protected]:8000",
    "http://user:[email protected]:8000",
]
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-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-User": "?1",
}
class DataDomeBypass:
    """
    Layered DataDome bypass combining:
    - TLS impersonation (curl_cffi)        → Layer 1
    - Geo-coherent headers                  → Layer 2
    - Residential proxy rotation            → Layer 3
    - Stealth browser (Playwright)          → Layer 4
    - Behavioral warm-up + human delays     → Layer 5
    """
    def _get_proxy(self) -> dict:
        p = random.choice(ПРОКСІ)
        return {"http": p, "https": p}
    def fetch_static(self, url: str, retries: int = 3) -> str | None:
        """For non-JS pages: fast, low-resource curl_cffi path."""
        for attempt in range(повторні спроби):
            try:
                session = cffi_requests.Session(impersonate="chrome")
                resp = session.get(
                    url,
                    headers=HEADERS,
                    proxies=self._get_proxy(),
                    timeout=15
                )
                if "datadome" in resp.cookies:
                    print(f"[Attempt {attempt+1}] DataDome cookie set - rotating...")
                    time.sleep(random.uniform(5, 10))
                    continue
                if resp.status_code == 200:
                    return resp.text
            except Exception as e:
                print(f"[Static] Error: {e}")
                time.sleep(random.uniform(2, 5))
        return None
    async def fetch_dynamic(self, url: str, base_url: str) -> str | None:
        """Для сторінок, що рендеряться JS: stealth Playwright із прогрівом."""
        proxy = random.choice(ПРОКСІ)
        async with async_playwright() as p:
            browser = await p.chromium.launch(
                headless=True,
                proxy={"server": proxy},
                args=["--disable-blink-features=AutomationControlled"]
            )
            context = await browser.new_context(
                viewport={"width": 1920, "height": 1080},
                user_agent=HEADERS["User-Agent"],
                locale="en-US",
                timezone_id="America/New_York",
            )
            page = await context.new_page()
            await stealth_async(page)
            # Warm up: homepage first, then target
            await page.goto(base_url, wait_until="domcontentloaded")
            await asyncio.sleep(random.uniform(2.0, 3.5))
            # Natural scroll on homepage
            for _ in range(random.randint(2, 4)):
                await page.mouse.wheel(0, випадковий.randint(100, 300))
                await asyncio.sleep(random.uniform(0.5, 1.2))
            # Now go to the actual target
            await page.goto(url, wait_until="networkidle")
            await asyncio.sleep(random.uniform(1.5, 3.0))
            content = await page.content()
            await browser.close()
            if "datadome" in content.lower() і "captcha" in content.lower():
                print("[Dynamic] CAPTCHA encountered - solver needed.")
                return None
            return content

12. Проблема підтримки, про яку ніхто не згадує

Ось що кожен туторіал із обходу DataDome зручно пропускає: це регулярно ламається.

DataDome безперервно оновлює свої моделі виявлення. Фінгерпринт, який працював минулого вівторка, може спричинити блокування вже наступного понеділка. Це playwright-stealth бібліотека — це відкритий проєкт спільноти, тож у ній немає команди інженерів, яка відстежує щотижневі релізи DataDome. Так само немає й undetected-chromedriver.

Підтримка production-стека для обходу DataDome вимагає (Scrapfly, 2026):

  • Відстеження змін фінгерпринтів із кожним великим релізом Chrome/Firefox
  • Періодична заміна позначених IP проксі
  • Оновлення поведінкових патернів у міру вдосконалення ML-моделей DataDome
  • Регресійне тестування всього вашого пайплайна після кожного оновлення бібліотеки

Для вебскрапінгу в малому масштабі або разових завдань це ще можна контролювати. Але для виробничих пайплайнів, що працюють у великому масштабі, ці витрати на супровід швидко накопичуються.

13. Коли слід перестати винаходити велосипед

У певний момент математика між власною розробкою і закупівлею змінюється. Якщо ваша команда витрачає більше часу на підтримку логіки обходу, ніж на отримання цінності з даних, щось не так.

Такі інструменти, як Web Unlocker від Bright Data обробляти всі п’ять рівнів виявлення одним викликом API — TLS-імперсонацію, ротацію резидентських проксі, браузерний фингерпринтинг, імітацію поведінки та розв’язання CAPTCHA — без того, щоб ви підтримували це самостійно. Їхній Scraping Browser відкриває сумісну з Playwright CDP-кінцеву точку, яка вже з коробки проходить перевірки DataDome.

(Повне розкриття: я не пов’язаний із Bright Data. Просто я неодноразово бачив, що в дослідницькій спільноті її згадують як один із небагатьох інструментів, який справді працює з DataDome-specific endpoint-ами, зокрема з mobile API шляхами.)

Формула, яка запускає перемикання:

  • Ви звертаєтеся до сайтів, захищених DataDome, на тисячі запитів на день
  • Ваша ціль змінює свого постачальника захисту від ботів без попередження
  • Your час вашої команди є ціннішим за вартість API для проксі/solver
  • Вам потрібні показники успішності 99%+ для подальших конвеєрів даних

Керована інфраструктура — це не спосіб зняти з себе відповідальність. Це правильний інструмент, коли вартість самостійного супроводу перевищує вартість підписки.

14. Правові та етичні аспекти

Перед тим як застосовувати будь-що з наведеного вище проти реальної цілі, пройдіть цей чекліст:

✅ Check robots.txt — це етичний сигнал і юридичне посилання в багатьох юрисдикціях (hiQ Labs v. LinkedIn, 9th Circuit 2022)

✅ Перегляньте Умови надання послуг — сайти, захищені DataDome, часто мають явні положення проти вебскрапінгу

✅ Уникайте персональних даних — GDPR і CCPA застосовуються до зібраної інформації про мешканців ЄС/Каліфорнії

✅ Обмежуйте частоту запитів відповідально — надмірне навантаження сервера може становити порушення CFAA у США

✅ Надавайте перевагу офіційним API — швидше, стабільніше та без юридичної двозначності

Scraping дані, доступні публічно для досліджень, моніторингу цін і конкурентної розвідки зазвичай вважається законним у США та ЄС, якщо ви не обходите межі автентифікації та не збираєте приватні дані користувачів. Якщо є сумніви, зверніться до юриста, який добре знається на праві цифрових прав, — цей ландшафт і далі змінюється.

Підсумок: чекліст обходу DataDome

Натисніть Enter або клацніть, щоб переглянути зображення у повному розмірі

Схожі записи