headless-browser について
Oxylabs Headless BrowserのリモートChromeセッションを使う開発者向けガイドです。CDP接続、セッション管理、プロキシや地域の設定、エラー処理とデバッグ手順を扱います。
主な機能
- 01WebSocket経由のリモートChrome接続
- 02Playwright、Puppeteer、CDPのガイド
- 03再試行とエラー処理のルール
- 04セッションプロファイルと再開
- 05ライブ検査と録画の手順
活用シーン
- 01PlaywrightやPuppeteerでのページ収集
- 02セッション再接続や障害への対応
- 03ジョブ間でのログイン状態の維持
- 04検査機能を使ったページ動作のデバッグ
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ oxylabs/ agent-skills --skill headless-browserインストール後、Claude Code で/headless-browserを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
errors.mdexamples.mdparameters.mdtargets.mdscripts/playwright_scrape.jsplaywright_scrape.py詳細
Oxylabs ヘッドレスブラウザー
検知回避、プロキシローテーション、ジオターゲティングを標準搭載したリモート Chrome セッションです。
ローカルでは何も実行されません。WebSocket で接続し、普段使用している CDP ライブラリでブラウザーを操作し、完了したらセッションを閉じます。このファイルにはルールを記載しています。詳細は関連ファイルにあります。
scripts/(コピーして使えるテンプレート)、parameters.md、errors.md、examples.md、targets.md。
1. 接続
| 項目 | 値 |
|---|---|
| エンドポイント | wss://USERNAME:[email protected] |
| 認証情報 | OXY_UNBLOCKER_USERNAME / OXY_UNBLOCKER_PASSWORD(エイリアス:OXY_HB_USERNAME / OXY_HB_PASSWORD) |
| オプション | URL クエリパラメーターのみ。例:?p_cc=US&session_name=job-42(parameters.md を参照) |
| ライブラリ | Playwright の chromium.connectOverCDP(推奨)、Puppeteer の puppeteer.connect、任意の CDP クライアント |
| ダッシュボード/サポート | https://hb.oxylabs.io/dashboard · [email protected] |
最もよくある 401 を防ぐためのルール:
wss://を使用してください。通常のws://も使用できますが、パスワードが暗号化されずに送信されます。- 未加工のパスワードを使って文字列連結で URL を組み立ててください。完成した URL を
new URL()やurllib.parseに渡さないでください。パスワードがパーセントエンコードされ、認証に失敗します。 - ダッシュボードに表示されているユーザー名を、
_ab12などのサフィックスも含めてそのまま使用してください。 - パスワードに
:が含まれている場合、URL では送信できません。新しいパスワードを依頼するか、Authorization: Basicヘッダーを自分で送信してください(examples.mdを参照)。 - 認証はパラメーターより先に確認されます。まず
401を修正してから、ほかの点を確認してください。
2. クイックスタート
最小構成(Playwright、JavaScript):
const { chromium } = require("playwright");
const url = `wss://${process.env.OXY_UNBLOCKER_USERNAME}:${process.env.OXY_UNBLOCKER_PASSWORD}@hb.oxylabs.io?p_cc=US`;
const browser = await chromium.connectOverCDP(url, { timeout: 60000 });
try {
const page = await browser.contexts()[0].newPage(); // default context: backed by fingerprint, proxy, o_profile
await page.goto("https://example.com", { waitUntil: "domcontentloaded", timeout: 30000 });
console.log(await page.content());
} finally {
await browser.close(); // always: an unclosed session keeps its concurrency slot
}
実際の作業では、再実装するのではなく scripts/playwright_scrape.js または scripts/playwright_scrape.py を丸ごとコピーして使用してください。これらのスクリプトには、このファイルのほかの箇所で前提としている次の5つの動作が追加されています。
- バックオフ付きで接続(基準1秒、上限60秒、ジッターあり、最大6回試行)。再試行可能なエラー(
429、5xx、CDP_SESSION_IN_USE、CDP_NO_BROWSERS_AVAILABLE、CDP_BROWSER_OVERWORKED、CDP_BAD_PROXY、CDP_GENERAL_ERROR、タイムアウト)の場合のみ実行します。400/401/403はリクエストに誤りがあることを示します。修正し、変更しないまま再試行しないでください。 - ログに記録する前に、すべてのエラーメッセージからパスワードを伏せ字にする。Playwright のエラーメッセージには接続 URL が含まれます。
- デフォルトで
image、stylesheet、media、fontをブロックする。時間がかかるうえ、データ抽出には不要です。 - ナビゲーション前にリスナーを登録する。
X-Error-Descriptionレスポンスヘッダーは、ページのトラフィックで発生した Oxylabs 側のエラーを示します。 finallyでbrowser.close()を実行し、全体に制限時間を設けて、セッションが応答しなくても必ず終了処理に到達するようにする。
Puppeteer、Python の非同期処理、生の CDP、セッションの引き継ぎ、プロファイル、記録、ファンアウトについては examples.md を参照してください。
3. セッションと制限
| 制限(アカウントのデフォルト値) | 値 | 超過時 |
|---|---|---|
| 1 秒あたりの新規セッション数 | 10 | 429 CDP_SESSION_RATE_LIMIT_REACHED(スペースの起動間隔は 150 ms 以上) |
| 同時セッション数 | 100 | 429 CDP_MAX_CONCURRENT_SESSIONS_REACHED |
| 名前付き(再開可能)セッション数 | 5 | 429 CDP_MAX_PERSISTENT_SESSIONS_REACHED |
保存済みプロファイル(o_profile)数 | 5 | 403 profile limit reached (5 profiles maximum) |
| 録画数 | 10 | 403 recording limit reached (10 recordings maximum) |
| 同時インスペクションビューアー数 | 10 | CDP_VNC_MAX_CONCURRENT_SESSIONS_REACHED |
session_name(^[A-Za-z0-9-]{3,36}$)を指定すると、切断後 10 分間 セッションを再開できます。 これを指定するとkeep_aliveも有効になります。keep_alive=trueだけを送信しないでください(400 keep_alive requires session_name)。- 古い接続がまだアタッチされた状態で再接続すると、
429 CDP_SESSION_IN_USEが返されます。先に古い接続を閉じてください。 - セッションの最長時間は 1 時間 です。長時間のジョブは複数のセッションに分けてください。
- 放棄されたセッションは同時実行枠を保持します(約 20 秒、名前付きの場合は最長 10 分)。その後、無関係に見える
429 CDP_MAX_CONCURRENT_SESSIONS_REACHEDが発生することがあります。Playwright/Puppeteer オブジェクトを閉じれば十分です。 browser.close()は、名前付きセッションが再開可能なままでも、開いているページと Cookie を消去します。セッションを 引き継ぐには、Puppeteer のbrowser.disconnect()を使用してください(examples.mdの「名前付きセッションの再開」を参照)。 セッション終了後も保持する必要がある状態(ログイン情報、クリアランス Cookie)は、キープアライブではなくo_profileに保存してください。- パラメーターの組み合わせが異なるごとに個別にプロビジョニングされます。ジョブの実行中は設定を変えないでください。
- 高負荷時は接続がキューに入り、約 1 分後に
503 queue timeoutで終了することがあります。時間をおいて再試行してください。 サポートに問い合わせると、制限を引き上げられます。
4. エラー
エラーは 3 つの経路で発生します。ハンドシェイク:HTTP ステータスと短い本文(Playwright の場合は WebSocket error: <URL with password> <status> の後に本文、Puppeteer の場合は Unexpected server response: <status>)。接続後:WebSocket がコード 3000 と CDP_* の理由で閉じます。この情報が見えるのは生のクライアントだけです。Playwright/Puppeteer では Target closed とだけ報告されるため、セッション開始直後の切断は再試行可能なものとして扱ってください。ページ内:拒否されたコマンド 1 件に対して CDP エラー 1337 が発生します。ページの通信で X-Error-Description を含むレスポンスは Oxylabs のネットワークエラーです(再試行してください)。これを含まないブロックページは対象側の判断です(再試行せず、アプローチを変えてください)。
connect failed?
├─ 401 ............ fix credentials/scheme, do not retry
├─ 400/403/409 .... fix the named parameter, do not retry unchanged (409: wait 30 s+ for the other session)
├─ 429 ............ backoff; if MAX_CONCURRENT: hunt for unclosed sessions
└─ 5xx/503 ........ backoff, up to ~2 min total
session dropped (close 3000)?
└─ new session with backoff; rotate sticky id on CDP_BAD_PROXY
navigate failed with 1337 Invalid target?
└─ stop; restricted target (section 7)
page shows block / 403 wall?
├─ X-Error-Description present .... Oxylabs network issue: backoff + retry
└─ absent ......................... target decision: change identity, geo, device, pacing (section 5)
原因と対処方法を含むすべてのメッセージテキストは errors.md を参照してください。
5. 対象サイトの安全性(DataDome など)
ほとんどのジョブで使うデフォルトのパラメーターセットは p_cc のみです。 すべてのセッションには、毎回新しいフィンガープリントと新しい住宅用 IP が割り当てられます。これは、単発の取得や、独立したページを並行して取得する場合に必要なものです。固定 IP と保存済みプロファイルは、特定の必要があるときに選択するツールであり、標準設定ではありません。
保護された対象サイトでの作業手順。 まず通常のスクリプトを書いて、動作する状態にします。ページごとに新しいセッションを使い、適切な地域とデバイスを設定し、人間らしいペースで操作してから、以下の段階的な対処を行います。それでも対処後に失敗する場合に限り、ユーザーに永続プロファイルを推奨します(以下のセットアップ/利用パターンと、期待できる効果およびコスト、つまりセットアップ手順とプロファイル上限の 5 件について説明します)。ユーザーの承諾を得てから実装してください。独断でプロファイルや固定 ID を追加してはいけません。
| 必要なこと | 追加するもの | 使用しないケース |
|---|---|---|
| 複数の接続を同一の訪問者に見せる(ログイン、カート、1 つのセッションを超えて続くフロー) | proxy_resi_ses_id + proxy_resi_ses_time | セッションごとに 1 ページを取得する場合 |
| Cookie やログイン状態をジョブ間で維持する(DataDome の解除状態、認証が必要なスクレイピング) | ユーザーの承諾後、セットアップ実行で一度作成する o_profile | 初回の試行、ブロックせずにコンテンツを提供する対象サイト |
| 10 分以内に同じブラウザーを再開する | session_name | それ以外すべて |
使用する場合、これらの組み合わせは 1 つの ID として扱われます。一貫性を保ってください。
setup, exactly once : ?o_profile=acme-us-01&o_profile_save=true&p_cc=US&proxy_resi_ses_id=acmeus01&proxy_resi_ses_time=30
consumers, any number: ?o_profile=acme-us-01&p_cc=US&proxy_resi_ses_id=acmeus01&proxy_resi_ses_time=30
- プロファイルは 1 回の実行で書き込み、ほかの実行で読み込みます。
o_profile_save=trueを送信する接続は、セットアップ実行のみです。セットアップ実行では Cookie を取得し(エントリーページのブロックを解除し、ログインします)、ページを検証してから終了します。利用側の実行ではo_profile=<name>のみを送信します。読み取り専用のため、書き込みロックも409もありません。利用側の実行でプロファイルを「補充」してはいけません。動作しなくなったら、新しい名前でセットアップを再実行します。本番環境では、プロファイルを準備・検証するセットアップサービスと、それを利用するだけの利用側サービスを用意します(examples.md、「プロファイルのセットアップと利用側の実行」)。 proxy_resi_ses_id+proxy_resi_ses_timeは送信元 IP を固定します(最長 1440 分)。固定 ID を使うとプロキシの自動再試行が無効になります。CDP_BAD_PROXYが発生した場合は、新しい ID に切り替えてください。- Cookie を持つ ID で
p_cc/p_city/p_stateを変更してはいけません。新しいプロファイルと固定 ID を開始してください。 - 操作は
p_deviceに合わせてください。mobileの場合はタップと小さなスクロールを使い、ホバーは使いません。desktop(デフォルト)の場合はその逆です。ビューポートやデバイスのメトリクスは自分で設定しないでください。フィンガープリントはサービスが管理します。 - 人間らしいペースを保ってください。ページ読み込みの間隔は 3~8 秒とし、クリックの前にスクロールし、1 つの ID につき一度に 1 ページだけ操作します。複数のタブではなく、複数の ID を並行して実行してください。
- ブロックされた場合は、新しい接続ごとに 1 段階ずつ対処します。新しいセッション → より広い地域(
p_cityを削除)→p_device=mobile→ 速度を落とす → 調査(セクション 6)→ ユーザーに永続プロファイルを推奨 → 停止して報告。同一のリクエストを繰り返しても、段階的な対処にはなりません。
ベンダーごとのブロックを示す特徴、推奨/非推奨の表、および保護された対象サイトでの初期設定値については、targets.md を参照してください。
6. 運用上の衛生管理
- デバッグ。 ツールが2つあります。ユーザーからデバッグ方法、ブラウザーの動作、または実行が失敗する理由を尋ねられた場合は、必ず両方を案内してください。ライブ検査(CDP コマンド
__session_idでセッション ID を取得し、https://hb.oxylabs.io/novnc/?id=<id>を開いて、実行中のセッションを確認します)と、録画(record=true&record_name=<job>を指定するとセッションの動画が保存され、後からhttps://hb.oxylabs.io/dashboardで再生できます。上限は10件です。古い録画はそこで削除してください)です。どちらもデフォルトでは無効です。同じターゲットで3回連続して失敗した後は、ページに実際に何が表示されているか確認するため、自分でもこれらを使用してください。スニペットはexamples.mdの「Session id, live inspection and recording」を参照してください。 - タイムアウト。 接続は60秒、ナビゲーションは30秒で、これに加えてジョブ全体の期限があります。
- ログ記録。 接続 URL や生のエラーメッセージは決して記録しないでください。パラメーターのセットとセッション ID を記録してください。
- コンテキスト。
browser.contexts()[0]を使用してください。newContext()はプロファイルストレージやフィンガープリントの調整から分離されています。
7. 制限対象
デフォルトでブロックされています。アクセスするには、アカウントマネージャーを通じて簡単な KYC を行う必要があります。対象は、エンターテインメントおよびストリーミング、銀行および金融、政府サイト、ゲームプラットフォーム、チケット販売、ウェブメール、広告ネットワーク、サードパーティーの IP チェッカーです。https://ip.oxylabs.io/location を使用して、出口 IP と地域を確認してください。ブロック対象にアクセスすると、CDP エラー 1337 Invalid target で Page.navigate が失敗します。
関連項目:scripts/(Playwright の完全なテンプレート、JS および Python)、parameters.md(すべてのパラメーターとその検証)、errors.md(すべてのメッセージ)、examples.md(Puppeteer、Python async、生の CDP、再接続、プロファイル、録画、ファンアウト)、targets.md(ブロック検出、DataDome のプレイブック)。