DataDome検出の仕組みと、正当な自動化がクリーンに通過する方法 — 技術深掘り

DataDomeはIPレピュテーション、JA3/JA4 TLSフィンガープリント、ブラウザフィンガープリント、行動シグナルを組み合わせてスクレイパーを検出します。本稿ではその検出スタックを解像度高く分解し、正当な自動化がresidentialプロキシとステルスブラウザでクリーンに通過する方法を解説します。

DataDome検出の仕組みと、正当な自動化がクリーンに通過する方法 — 技術深掘り

DataDome検出に直面したスクレイピングエンジニアへ

データパイプラインを構築中、突然 datadome Cookieを伴うCAPTCHAページにリダイレクトされ、リクエストが全てブロックされる——この経験をしたスクレイピングエンジニアは少なくないでしょう。DataDomeは、フランスを拠点とするボット検出プラットフォームで、世界中の大手サイトに導入されています。

本稿では、DataDomeの検出スタックを技術的に分解し、正当な自動化がどのようにクリーンに通過するかを解説します。ここでの「正当な自動化」とは、セキュリティ研究、認可されたペンテスト、公開データの合法的な収集などを指します。DataDomeを「突破」するハックではなく、検出シグナルを理解し、正当なトラフィックとして認識されるための正しいアプローチを示します。

DataDomeの検出スタック — 4層のシグナル統合

DataDomeは単一のシグナルではなく、複数レイヤーのシグナルを統合して判定を行います。各レイヤーが独立してスコアを生成し、それらがエンsembleされて最終的なボット/人間判定が下されます。

第1層: IPレピュテーションとASN分析

DataDomeは、リクエスト元IPアドレスを複数の商用IPレピュテーションデータベースと照合します。具体的には以下を評価します:

  • ASNタイプ: データセンターASN(OVH、Hetzner、DigitalOceanなど)からのリクエストは高スコアフラグ。ISP/モバイルキャリアASNは低スコア。
  • IP範囲の分類: 商用データベースが「hosting」「proxy」「tor exit」と分類するIP範囲を即座にフラグ。
  • 地理的一貫性: IPのGeoIP位置とリクエストのAccept-Languageヘッダー、タイムゾーンオフセットの不一致を検出。
  • IPの過去行動: 同一IPからの過去リクエストパターン(レート、ボリューム、CAPTCHA解決履歴)をスコアリング。

これが、DataDome residential proxiesが重要になる理由です。データセンターIP範囲はDataDomeにとって「即座に疑わしい」シグナルであり、他のシグナルが完璧であっても初期スコアが高くなります。

第2層: TLSフィンガープリンティング (JA3/JA4)

TLSハンドシェイクは、HTTPリクエストが送信されるに発生します。つまり、DataDomeはリクエスト内容を見る前に、TLSクライアント_helloの内容だけでスコアリングを開始できます。

JA3フィンガープリントは以下のTLSパラメータをMD5ハッシュ化したものです:

  • TLSバージョン
  • 対応暗号スイート(cipher suites)の順序付きリスト
  • 対応拡張機能(extensions)のリスト
  • 対応楕円曲線(elliptic curves)
  • 対応楕円曲線ポイントフォーマット

JA4フィンガープリントはJA3の後継で、より細かな情報をエンコードします:

  • 暗号スイート数、拡張機能数などのメタデータ
  • ALPNプロトコル(h2, http/1.1など)の順序
  • SNIの有無

具体的に何が検出されるか:

  • Python requests: 暗号スイート順序がChrome/Firefoxと異なり、拡張機能が少ない。JA3ハッシュが既知のボットリストと一致。
  • Go標準ライブラリ: TLS 1.3対応が限定的で、Chromeのcipher orderingと異なる。
  • 古いSelenium: TLSフィンガープリントがブラウザバージョンと一致しない場合、改変が疑われる。

DataDomeは、JA3/JA4ハッシュを既知のボットシグネチャデータベースと照合するだけでなく、同一セッション内の複数リクエストでJA3が変化すること(プロキシローテーションによるTLS再ネゴシエーション)も検出します。

第3層: ブラウザフィンガープリンティング

DataDomeのクライアントサイドJavaScriptは、ブラウザの環境特性を大量に収集します。主要なシグナルは以下の通り:

Canvas フィンガープリント:

  • 隠しCanvas要素にテキストと図形を描画し、toDataURL() の出力をハッシュ化。
  • GPU、ドライバ、フォントレンダリングエンジンの違いがハッシュ値に反映。
  • ヘッドレスモードのChromeはCanvas描画結果が通常Chromeと異なる場合がある(SwiftShaderによるソフトウェアレンダリング)。

WebGL フィンガープリント:

  • WEBGL_debug_renderer_info 拡張からGPUレンダラとベンダーを取得。
  • ヘッドレスChromeは Google SwiftShader を返すことが多く、これが強いボットシグナル。
  • WebGL描画テストのピクセルレベル差分も検出。

Audio フィンガープリント:

  • OfflineAudioContext でオーディオ信号を処理し、結果の浮動小数点値をハッシュ化。
  • オーディオスタックの実装差異(OS、ドライバ、ハードウェア)を検出。

Navigator プロパティ:

  • navigator.webdrivertrue の場合、Selenium/Playwright制御下であることが即座に判明。
  • navigator.pluginslanguagesplatformhardwareConcurrency の一貫性チェック。
  • navigator.userAgentnavigator.appVersion の不一致検出。

DataDomeはこれらのシグナルを個別に評価するだけでなく、シグナル間の一貫性を検証します。例えば、User-Agentが「Windows Chrome」を主張しているのに、プラットフォームが「MacIntel」、CanvasハッシュがLinuxのパターン——このような矛盾は強いボットスコアを生成します。

第4層: 行動シグナル (Behavioral Analytics)

静的フィンガープリントを通過しても、DataDomeは行動パターンでボットを検出します:

  • マウスダイナミクス: マウス移動の速度、加速度、曲率、マイクロムーブメント。人間のマウス軌跡はベジエ曲線的で、ボットの直線移動とは異なる。
  • スクロールパターン: スクロール速度の変動、一時停止、方向変更の頻度。
  • キーストロークタイミング: キー押下間隔の分布。人間は正規分布に近い間隔だが、ボットは一定間隔またはランダム均一分布。
  • ページ滞在時間とインタラクション密度: ページ読み込みから最初のインタラクションまでの時間、インタラクションの頻度。
  • リクエストタイミング: 連続リクエスト間隔の規則性。ミリ秒単位の一定間隔はボットシグナル。

DataDomeはこれらの行動データを機械学習モデルに入力し、リアルタイムでスコアを更新します。

datadome CookieとCAPTCHAチャレンジフロー

DataDomeのチャレンジフローを理解することは、検出メカニズム全体を把握する鍵です:

  1. 初回リクエスト: クライアントがサイトにアクセス。DataDomeのエッジノードがリクエストを傍受。
  2. サーバーサイド評価: IP、TLS、HTTPヘッダーをスコアリング。スコアが閾値以下ならリクエストを通過。
  3. JavaScript チャレンジ: スコアが中間領域の場合、DataDomeのJSタグがブラウザフィンガープリントと行動データを収集。
  4. datadome Cookie 付与: 評価が合格すると、datadome Cookieがセットされる。このCookieには暗号化されたセッションデータが含まれ、後続リクエストでサーバーサイド評価をバイパスできる。
  5. CAPTCHA チャレンジ: スコアが閾値を超える場合、CAPTCHA(DataDome独自またはreCAPTCHA/hCaptcha統合)が表示される。
  6. CAPTCHA 解決後: 成功すると datadome Cookieが付与され、通常アクセスに復帰。

重要なポイント: datadome Cookieには有効期限があり、期限切れ後は再評価が行われます。また、Cookieの不正検出も行われており、偽造Cookieは即座にブロックされます。

なぜResidential・Mobileプロキシが重要か

DataDomeのIP評価において、データセンターIPは初期スコアが既に高い状態でスタートします。これは「bypass DataDome」を考える上で最も重要な前提です:

IPタイプASN例DataDome初期スコア備考
データセンターOVH, Hetzner, AWS高(即ブロックの可能性)商用DBで「hosting」分類
ResidentialAT&T, Comcast, NTT低〜中ISP ASN、住宅IP
MobileDocomo, Vodafone, T-Mobile最低キャリアASN、最も信頼性が高い
Tor Exit各Tor出口ノード最高(即ブロック)既知のTor出口リストと照合

データセンターIPでどれだけブラウザフィンガープリントを完璧に偽装しても、IPレピュテーション層で高スコアが付くため、CAPTCHAチャレンジが頻繁に発生します。一方、ResidentialプロキシはISP ASNを持つため、初期スコアが低く、他のシグナルも適切であればスムーズに通過します。

Mobileプロキシはさらに有利です。DataDomeはモバイルトラフィックを「最も人間らしい」と評価する傾向があり、モバイルキャリアASNからのリクエストは初期スコアが最低になります。

正当な自動化の構成 — Playwright Stealth + Residentialプロキシ

ここからは、正当な自動化がDataDomeの検出をクリーンに通過するための具体的な実装を示します。セキュリティ研究や認可されたデータ収集において、検出シグナルを最小化することは正当な目的です。

実装例1: Playwright Stealth + ProxyHat Residentialプロキシ (Python)

以下は、PlaywrightのstealthプラグインとProxyHatのresidentialプロキシを組み合わせた基本的な構成です:

from playwright.sync_api import sync_playwright
from playwright_stealth import stealth_sync

PROXY = {
    "server": "http://gate.proxyhat.com:8080",
    "username": "user-country-US-session-stable01",
    "password": "YOUR_PASSWORD",
}

def scrape_with_datadome_protection(url: str):
    with sync_playwright() as p:
        browser = p.chromium.launch(
            headless=False,  # ヘッドレスモードは検出リスクが高い
            proxy=PROXY,
            args=[
                "--disable-blink-features=AutomationControlled",
            ],
        )
        context = browser.new_context(
            viewport={"width": 1920, "height": 1080},
            locale="en-US",
            timezone_id="America/New_York",
            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"
            ),
        )
        page = context.new_page()
        stealth_sync(page)

        # 人間らしいインタラクションをシミュレート
        page.goto(url, wait_until="domcontentloaded")
        page.wait_for_timeout(2000 + len(url) % 1000)  # ランダムな待機

        # マウス移動を人間らしく
        page.mouse.move(400, 300)
        page.mouse.move(600, 350, steps=15)
        page.wait_for_timeout(500)

        # スクロール
        page.evaluate("window.scrollBy(0, 300)")
        page.wait_for_timeout(800)

        content = page.content()
        browser.close()
        return content

ポイント:

  • headless=False: ヘッドレスモードはCanvas/SwiftShader検出のリスクがあるため、可能な限り避ける。
  • stealth_sync(page): navigator.webdriver の除去、Chrome DevTools Protocolの検出回避などを実行。
  • プロキシの country-US: ターゲットサイトのGeoと一致するIPを使用し、地理的一貫性を確保。
  • session-stable01: スティッキーセッションで同一IPを維持し、datadome Cookieを再利用可能に。

実装例2: Node.js + Playwright Stealth + SOCKS5

Node.js環境での実装例です。SOCKS5プロキシを使用する場合:

const { chromium } = require('playwright');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');

(async () => {
  const browser = await chromium.launch({
    headless: false,
    proxy: {
      server: 'socks5://gate.proxyhat.com:1080',
      username: 'user-country-FR-city-paris-session-abc456',
      password: 'YOUR_PASSWORD',
    },
  });

  const context = await browser.newContext({
    viewport: { width: 1366, height: 768 },
    locale: 'fr-FR',
    timezoneId: 'Europe/Paris',
    userAgent:
      'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ' +
      'AppleWebKit/537.36 (KHTML, like Gecko) ' +
      'Chrome/125.0.0.0 Safari/537.36',
  });

  const page = await context.newPage();

  // Stealth設定を適用
  await page.addInitScript(() => {
    Object.defineProperty(navigator, 'webdriver', { get: () => false });
    // Chrome自動化検出の無効化
    window.chrome = { runtime: {} };
  });

  await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });

  // 人間らしいマウス移動
  await page.mouse.move(300, 200);
  await page.waitForTimeout(1200);
  await page.mouse.move(500, 280, { steps: 20 });
  await page.waitForTimeout(600);

  // スクロール動作
  await page.evaluate(() => window.scrollBy(0, 250));
  await page.waitForTimeout(900);

  const content = await page.content();
  await browser.close();
  return content;
})();

実装例3: curlでのシンプルなResidentialプロキシ確認

ブラウザを使わず、単純なHTTPリクエストでIPとGeoを確認する例です:

# HTTPプロキシでIP確認
curl -x "http://user-country-DE:YOUR_PASSWORD@gate.proxyhat.com:8080" \
  https://httpbin.org/ip

# SOCKS5プロキシでIP確認
curl -x "socks5://user-country-DE:YOUR_PASSWORD@gate.proxyhat.com:1080" \
  https://httpbin.org/ip

# Accept-Languageとタイムゾーンの一貫性確認
curl -x "http://user-country-DE-city-berlin:YOUR_PASSWORD@gate.proxyhat.com:8080" \
  -H "Accept-Language: de-DE,de;q=0.9,en;q=0.1" \
  -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \
  https://httpbin.org/headers

この確認は、プロキシのGeoとHTTPヘッダーが一貫しているかを検証する重要なステップです。DataDomeは Accept-Language とIPのGeoの不一致を検出シグナルとして使用します。

各シグナルレイヤーの対策まとめ

これまでの内容を、検出レイヤーごとの対策として整理します:

検出レイヤー検出シグナル正当な自動化での対策
IPレピュテーションデータセンターASN、IP範囲分類Residential/Mobileプロキシの使用(ProxyHat
TLS (JA3/JA4)暗号スイート順序、ALPN、拡張機能実際のブラウザ(Playwright)を使用。Python requestsは避ける。
ブラウザFPCanvas, WebGL, Audio, NavigatorStealthプラグイン + ヘッドレス回避。SwiftShader検出に注意。
行動シグナルマウス、スクロール、タイミング人間らしいインタラクションのシミュレート。一定間隔リクエストの回避。
Cookie一貫性datadome Cookieの偽造検出Cookieの偽造は不可。正規フローで取得したCookieを再利用。

倫理的フレーミング — DataDomeは何を守っているか

技術的な対策を語る上で、倫理的コンテキストは不可欠です。

DataDomeは、Webサイトを悪意のあるボット攻撃から守るために存在しています。具体的には:

  • クレデンシャルスタッフィング: 流出したアカウント情報を使った不正ログイン試行
  • スクレイピングによる競合価格監視: 競合が自社価格を大量に収集する行為
  • DDoS攻撃: 大量リクエストによるサービス妨害
  • アカウント乗っ取り: ブルートフォース攻撃による不正アクセス

正当な自動化を行うエンジニアは、以下を遵守すべきです:

  • レート制限を尊重する: 1秒間に数十リクエストを送るのは、DataDomeの保護目的と衝突する。
  • CAPTCHAソルバーを使用しない: CAPTCHAが表示されたら、それは「自動化を止めろ」というシグナル。ソルバーで突破するのは倫理的ではない。
  • robots.txtを確認する: サイト管理者がクロールを拒否しているパスは尊重する。
  • 利用規約を確認する: サイトのToSがスクレイピングを明示的に禁止している場合は、公式APIを使用する。

正当なセキュリティ研究や認可されたペンテストでは、対象サイトの許可を得た上で、適切なペースとプロキシ設定でアクセスすることが基本です。

「公式APIを使え」が正解の場合

DataDomeが保護しているサイトの多くは、公式APIを提供しています。スクレイピングが困難な場合、まず公式APIの存在を確認すべきです:

  • 大手ニュース出版社: 多くがRSSフィードやNews APIを提供。スクレイピングよりも安価で安定。
  • 一部Eコマース: Product APIやAffiliate APIを提供。価格データはAPI経由で取得可能。
  • SNSプラットフォーム: Twitter/X、Instagramなどは公式APIがあり、スクレイピングはToS違反。

公式APIが存在しない、またはAPIが提供しないデータが必要な場合のみ、正当なスクレイピングを検討してください。

ProxyHat Residentialプロキシの設定詳細

ProxyHatのresidentialプロキシを使用する際の主要な設定オプションを整理します:

パラメータ説明
country国コード(ISO 3166-1 alpha-2)user-country-US
city都市指定(対応都市のみ)user-country-DE-city-berlin
sessionスティッキーセッションIDuser-session-abc123

DataDome対策では、スティッキーセッションが重要です。IPローテーションごとに datadome Cookieが無効になるため、セッション中は同じIPを維持する必要があります:

# スティッキーセッションでIPを維持
# セッションIDが同じ限り、同じIPが割り当てられる
PROXY_URL = "http://user-country-US-session-mysession01:YOUR_PASSWORD@gate.proxyhat.com:8080"

# セッションを切り替える場合は新しいIDを使用
PROXY_URL_2 = "http://user-country-US-session-mysession02:YOUR_PASSWORD@gate.proxyhat.com:8080"

Key Takeaways

  • DataDomeは多層検出: IP、TLS、ブラウザFP、行動シグナルの4層で評価。単一レイヤーの対策だけでは不十分。
  • データセンターIPは初期ハンディキャップ: DataDomeはデータセンターASNを高スコア扱い。Residential/Mobileプロキシが必須。
  • 実際のブラウザを使う: Python requestsやGo標準ライブラリはTLSフィンガープリントで検出される。Playwright + Stealthを使用。
  • 行動シミュレーションが鍵: マウス移動、スクロール、リクエスト間隔を人間らしく設計。
  • Geo一貫性を確保: プロキシのIP地域と、Accept-Language、タイムゾーンを一致させる。
  • 倫理を守る: CAPTCHAソルバーは使わない。レート制限を尊重。公式APIがあるならそちらを使う。

正当な自動化でDataDome保護サイトにアクセスする必要がある場合、ProxyHatのresidentialプロキシで適切なGeo設定とスティッキーセッションを構成できます。詳細なロケーション対応はロケーション一覧を参照してください。

Webスクレイピング全般のベストプラクティスについては、Webスクレイピングのベストプラクティスも併せてご覧ください。

始める準備はできましたか?

AIフィルタリングで148か国以上、5,000万以上のレジデンシャルIPにアクセス。

料金を見るレジデンシャルプロキシ
← ブログに戻る