Playwright プロキシ統合: ブラウザ、コンテキスト、ローテーション

Playwright は、認証済みプロキシがそのまま動作する唯一の主要なブラウザフレームワークです。認証情報は一級の設定として扱われます。コンテキストにおける活用が鍵です: 一つのブラウザで、ジョブごとに異なる出口IPを使用します。以下がその完全なパターンです。

Playwright は、認証済みプロキシが一級市民として扱われる唯一の主要なブラウザ自動化フレームワークです: ユーザー名とパスワードは単なる設定フィールドであり、拡張機能のハックも、認証ダイアログも、ラッパーライブラリも必要ありません。これにより、基本的な Playwright プロキシ設定は Node または Python で5行で完了します。本当の強みはもう一段階深いところにあります — コンテキストごとのプロキシにより、一つのブラウザプロセスで多くの独立したセッションを実行でき、それぞれが独自の出口IPを持ちます。これはどのフレームワークでも最も安価なローテーションアーキテクチャです。このガイドでは、両方のレイヤー、SOCKS5 とローカルホストの注意点、プロキシが帯域幅の請求に与える影響、そしてステルスが本当に終わる場所をカバーします。

ブラウザ起動時の Playwright プロキシ

launch()proxy オブジェクトを渡すと、ブラウザ内のすべてのページがそれを経由してルーティングされます。形状に注意してください: サーバーURLには認証情報が含まれていません — それらは別の usernamepassword フィールドに入ります。これにより、Playwright は Selenium や Puppeteer を悩ませる認証ポップアップ問題を回避します:

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({
    proxy: {
      server: 'http://gate.quantumproxies.io:PORT',
      username: 'USER',
      password: 'PASS',
    },
  });
  const page = await browser.newPage();
  await page.goto('https://httpbin.org/ip');
  console.log(await page.textContent('body')); // proxy exit IP
  await browser.close();
})();

Python API はそれを正確に反映しています:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(proxy={
        "server": "http://gate.quantumproxies.io:PORT",
        "username": "USER",
        "password": "PASS",
    })
    page = browser.new_page()
    page.goto("https://httpbin.org/ip")
    print(page.text_content("body"))
    browser.close()

標準の http://user:pass@host:port 文字列に認証情報がある場合は、文字列操作ではなく URL クラス (new URL() in Node, urllib.parse in Python) を使用して分割してください — 特殊文字を含むパスワードがその方法で生き残ります。テストランナーの注意点: playwright.config.tsuse.proxy はテストをカバーしますが、混合設定での設定レベルのプロキシ設定が無視されるという長年の報告があるため、スクレイピングスクリプトでは常に launch() またはコンテキストで直接プロキシを設定してください。

コンテキストごとのプロキシ: 新しいブラウザなしでのローテーション

BrowserContext はブラウザ内の隔離されたブラウザです: クッキー、ストレージ、キャッシュが分離され、プロセスのみを共有します。コンテキストは独自の proxy オプションを受け入れ、作成にはフル起動の数秒に対して数ミリ秒しかかかりません — したがって、ローテーションパターンは一つのブラウザ、ジョブごとのコンテキストです:

const { chromium } = require('playwright');

const PROXY = {
  server: 'http://gate.quantumproxies.io:PORT',
  username: 'USER',
  password: 'PASS',
};

(async () => {
  const browser = await chromium.launch();
  const urls = ['https://example.com/a', 'https://example.com/b'];

  for (const url of urls) {
    const context = await browser.newContext({ proxy: PROXY });
    const page = await context.newPage();
    try {
      await page.goto(url, { timeout: 30000 });
      // ...extract...
    } finally {
      await context.close(); // frees cookies, cache, session
    }
  }
  await browser.close();
})();

ローテーションゲートウェイを指すと、すべてのコンテキストが90M+の住宅用プール内の異なるIPから出力され、リスト管理は不要です — これがサーバー側での ローテーションプロキシ の役割です。ジョブが複数のページにわたって同じIPを必要とする場合(ログインとチェックアウト)、ユーザー名パラメータを介してスティッキーセッションを要求すると、セッションウィンドウ中は出口が保持されます。コンテキストは失敗も隔離します: 禁止された出口はコンテキストと共に終了し、ブラウザ全体を汚染することはありません。

同じパターンでジオターゲティングが無料で得られます。プロキシがコンテキストオプションであるため、一つのブラウザで米国のコンテキスト、ドイツのコンテキスト、日本のコンテキストを同時に保持できます — それぞれがローカルの出口IPからローカライズされた価格、検索結果、同意バナーを表示します。価格比較や広告検証の作業では、これが3つのクラウドリージョンを3行の設定に置き換えます。

Playwright プロキシローテーションの図: 一つのブラウザプロセスに複数の隔離されたコンテキストがあり、それぞれが異なる住宅用出口IPを経由する
コンテキストは Playwright のローテーション単位です: 同じプロセス、別のアイデンティティ、独自のプロキシ。コンテキストの起動はミリ秒単位で、ブラウザは秒単位です。

SOCKS5、バイパスルール、ローカルホストの罠

スケールする前に帯域幅を削減

レンダリングブラウザはすべてをダウンロードします — 画像、フォント、アナリティクス、広告スクリプト — そしてメータリングされた住宅用トラフィックを通じてそのすべての費用を支払います。非必須のリソースタイプをブロックすることで、通常はページごとの転送を半分以上削減できます。そして Playwright のルーティングにより、コンテキストでワンライナーで実行できます。詳細は プロキシ帯域幅コスト削減 ガイドにあります:

await context.route('**/*', (route) => {
  const type = route.request().resourceType();
  if (type === 'image' || type === 'font' || type === 'media') {
    return route.abort();
  }
  return route.continue();
});

効果を仮定するのではなく測定してください: コンテキストのレスポンスイベントを購読し、ルートありとなしのページサンプルの転送サイズを合計すると、実際のページごとのGBコストが得られます — これは100万ページのクロールが丸め誤差か予算項目かを決定する数値です。

ステルスの限界: プロキシでは修正できないもの

限界を正直に認識しましょう。住宅用出口はIPの評判を解決します — 最初で最大のフィルターですが、Playwright はネットワーク層の上に自動化の痕跡を残します: ヘッドレスレンダリングの癖、CDPのアーティファクト、アンチボットベンダーが直接調査するフィンガープリントの表面。ステルスプラグインはいくつかのシグナルを修正し、他のものでは検出器の更新に遅れを取ります; それは設定で有効にするものではなく、あなたが引き継ぐ軍拡競争です。実用的な分割: 通常のサイトの長い尾のために Playwright を 住宅用プロキシ を通して実行し、本当に敵対的なドメインを Scraper API にルーティングして、フィンガープリント、レンダリング、リトライを管理し、HTML、Markdown、または構造化されたJSONを返すようにします。Playwright コードは独自に優れたインタラクションフローを続け、フェッチとパースのジョブはAPIに移行します。同じ計算は PuppeteerSelenium にも適用されます; フレームワークの交換ではフィンガープリントの問題は解決しません。

Playwright プロキシが修正するものとブラウザフィンガープリントがまだブロックするものを示す壁の図、スクレーパーAPIへのエスカレーション
クリーンなIPは最初の壁を突破します。フィンガープリントチェックは2番目の壁です — そしてAPIが別のステルスパッチに勝るポイントです。

よくある質問

Playwright Python でプロキシを設定するにはどうすればよいですか?

launch() にプロキシ辞書を渡します: p.chromium.launch(proxy={"server": "http://host:port", "username": "USER", "password": "PASS"})。同じ辞書は browser.new_context() でもコンテキストごとのルーティングに使用できます。認証情報は常にサーバーURLの中ではなく、別のフィールドに入れます。

Playwright はコンテキストごとに異なるプロキシを使用できますか?

はい — 各 newContext() 呼び出しに proxy オプションを渡します。コンテキストはブラウザプロセス以外は何も共有しないため、異なるプロキシを持つ2つのコンテキストはターゲットサイトにとって2つの無関係なブラウザのように振る舞います。これが標準のローテーションパターンです: 一度起動し、次にジョブまたはアイデンティティごとに新しいコンテキストを作成します。

Playwright は SOCKS5 プロキシ認証をサポートしていますか?

いいえ。Playwright は SOCKS5 をブラウザに渡し、Chromium には SOCKS 認証のメカニズムがないため、認証された SOCKS5 エンドポイントは失敗します。同じプロキシゲートウェイの HTTP(S) ポートを使用し、ユーザー名とパスワードフィールドを使用するか、IPホワイトリストで認証してください。SOCKS5 スキームを維持します。

正しい Playwright プロキシ形式は何ですか?

server フィールド (scheme://host:port — http, https または socks5) に加えて、オプションの usernamepasswordbypass フィールドを持つオブジェクトです。認証情報をサーバーURLの中に入れないでください; Playwright はそれらを別々に期待しており、特殊文字を含むパスワードは専用フィールドでのみ生き残ります。

なぜ Playwright プロキシがローカルホストで動作しないのですか?

Chromium はデフォルトでループバックアドレスのプロキシをバイパスするため、localhost127.0.0.1 へのリクエストは直接行き、設定を無視しているように見えます。httpbin.org/ip のような外部URLでプロキシを確認してください。テスト設定では、設定ファイルオプションに頼るのではなく、launch() でプロキシを設定することをお勧めします。

Playwright のプロキシストーリーはエコシステムの中で最もクリーンです: 設定としての認証情報、ローテーション単位としてのコンテキスト、帯域幅バルブとしてのルーティング。下にあるIPの質を正しく設定すれば、フレームワークは背景に消えます — それが良いインフラストラクチャのあるべき姿です。

Playwright を住宅用プロキシに向ける