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.webdriverがtrueの場合、Selenium/Playwright制御下であることが即座に判明。navigator.plugins、languages、platform、hardwareConcurrencyの一貫性チェック。navigator.userAgentとnavigator.appVersionの不一致検出。
DataDomeはこれらのシグナルを個別に評価するだけでなく、シグナル間の一貫性を検証します。例えば、User-Agentが「Windows Chrome」を主張しているのに、プラットフォームが「MacIntel」、CanvasハッシュがLinuxのパターン——このような矛盾は強いボットスコアを生成します。
第4層: 行動シグナル (Behavioral Analytics)
静的フィンガープリントを通過しても、DataDomeは行動パターンでボットを検出します:
- マウスダイナミクス: マウス移動の速度、加速度、曲率、マイクロムーブメント。人間のマウス軌跡はベジエ曲線的で、ボットの直線移動とは異なる。
- スクロールパターン: スクロール速度の変動、一時停止、方向変更の頻度。
- キーストロークタイミング: キー押下間隔の分布。人間は正規分布に近い間隔だが、ボットは一定間隔またはランダム均一分布。
- ページ滞在時間とインタラクション密度: ページ読み込みから最初のインタラクションまでの時間、インタラクションの頻度。
- リクエストタイミング: 連続リクエスト間隔の規則性。ミリ秒単位の一定間隔はボットシグナル。
DataDomeはこれらの行動データを機械学習モデルに入力し、リアルタイムでスコアを更新します。
datadome CookieとCAPTCHAチャレンジフロー
DataDomeのチャレンジフローを理解することは、検出メカニズム全体を把握する鍵です:
- 初回リクエスト: クライアントがサイトにアクセス。DataDomeのエッジノードがリクエストを傍受。
- サーバーサイド評価: IP、TLS、HTTPヘッダーをスコアリング。スコアが閾値以下ならリクエストを通過。
- JavaScript チャレンジ: スコアが中間領域の場合、DataDomeのJSタグがブラウザフィンガープリントと行動データを収集。
- datadome Cookie 付与: 評価が合格すると、
datadomeCookieがセットされる。このCookieには暗号化されたセッションデータが含まれ、後続リクエストでサーバーサイド評価をバイパスできる。 - CAPTCHA チャレンジ: スコアが閾値を超える場合、CAPTCHA(DataDome独自またはreCAPTCHA/hCaptcha統合)が表示される。
- CAPTCHA 解決後: 成功すると
datadomeCookieが付与され、通常アクセスに復帰。
重要なポイント: datadome Cookieには有効期限があり、期限切れ後は再評価が行われます。また、Cookieの不正検出も行われており、偽造Cookieは即座にブロックされます。
なぜResidential・Mobileプロキシが重要か
DataDomeのIP評価において、データセンターIPは初期スコアが既に高い状態でスタートします。これは「bypass DataDome」を考える上で最も重要な前提です:
| IPタイプ | ASN例 | DataDome初期スコア | 備考 |
|---|---|---|---|
| データセンター | OVH, Hetzner, AWS | 高(即ブロックの可能性) | 商用DBで「hosting」分類 |
| Residential | AT&T, Comcast, NTT | 低〜中 | ISP ASN、住宅IP |
| Mobile | Docomo, 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を維持し、datadomeCookieを再利用可能に。
実装例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は避ける。 |
| ブラウザFP | Canvas, WebGL, Audio, Navigator | Stealthプラグイン + ヘッドレス回避。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 | スティッキーセッションID | user-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スクレイピングのベストプラクティスも併せてご覧ください。






