Zendriver プロキシの認証: 設定と回避策

Zendriver は nodriver のコミュニティが維持するフォークで、修正が速いですが、同じ認証プロキシのギャップがあります。ここでは、プロキシの完全な設定、実際に異なる点、そしてユーザー名とパスワードを機能させるための回避策を紹介します。

zendriver プロキシ は nodriver と全く同じように設定されます。これは良いニュースでもあり、注意点でもあります。zendriver (cdpdriver/zendriver プロジェクト) は nodriver のコミュニティが維持するフォークで、非同期優先の、未検出のブラウザ自動化フレームワークであり、Chrome を DevTools プロトコルを通じて直接操作し、WebDriver は使用しません。これは nodriver の単一のメンテナーが外部の修正をほとんどマージしなかったために存在し、コミュニティがバグ修正を受け入れ、機能を追加し、GitHub で問題を受け入れるためにフォークしました。修正されなかったのは認証付きプロキシです。このガイドでは、プロキシの完全な設定、nodriver から実際に異なる点、そして user:pass を機能させるための回避策を紹介します。

インストールと基本的なプロキシ設定

インストールは一行で完了します — pip install zendriver — そして API は nodriver とほぼ同じで、スクリプトを移植する際に import zendriver as zd が唯一の変更となることがよくあります。認証なしのプロキシは browser_args を通じて行われ、リクエストはプロキシ IP から出ます。

import zendriver as zd

async def main():
    browser = await zd.start(
        browser_args=["--proxy-server=gate.quantumproxies.io:PORT"],
    )
    page = await browser.get("https://httpbin.org/ip")
    print(await page.get_content())   # shows the proxy exit IP
    await browser.stop()

zd.loop().run_until_complete(main())

これは単なる Chrome フラグであるため機能します。認証情報を追加すると — --proxy-server=http://USER:PASS@host:port — Chromium は USER:PASS@ 部分を静かに破棄し、プロキシは 407 で応答し、zendriver が埋められないネイティブのログインダイアログが表示されます。これは Chrome の制限であり、zendriver のバグではないため、フラグがパスワードを受け入れるようにするバージョンアップはありません。

zendriver プロキシ認証のギャップ

このギャップは zendriver の問題で公然と追跡されています — 機能要求スレッド (#10) と専用の「認証付きプロキシ」問題 (#208) — これは注目に値する違いです: nodriver では同じ質問がメンテナーが一度回答して終わった議論に埋もれています。問題 #10 の一人のユーザーは現状を率直にまとめています: プロキシサーバーオプションには認証する方法がないため、代わりにプロキシ拡張を使用しており、それがうまく機能しています。これは現場でテストされたコンセンサスであり、nodriver ユーザーが頼る同じ3つの修正を直接指し示しています。

修正 1: IP ホワイトリスト化 (最も簡単)

もしあなたのジョブが安定したパブリック IP を持つマシンから実行される場合、認証情報を完全にスキップします。プロバイダのダッシュボードで出口 IP を登録し、ゲートウェイがソースアドレスであなたを認証します — zendriver コードは上記の --proxy-server スニペットのままで、認証ロジックはゼロです。すべての QuantumProxies プランは IP ホワイトリスト化を user:pass と並行してサポートしており、IP が固定されている場合にはデフォルトの推奨事項となります。唯一の制限は、スクリプトではなくマシンを認証することですので、NAT の背後にある一時的なランナーやコンテナは次の2つの方法のいずれかを必要とします。

nodriver と zendriver の比較: 共有された CDP アーキテクチャとプロキシ認証のギャップ、しかし異なるメンテナンスモデル
zendriver は nodriver のステルス性と API を維持しながら、オープンな問題トラッカーを追加しています — しかしプロキシ認証のギャップは変更されずに引き継がれています。

修正 2: CDP を介してチャレンジに応答する

zendriver は nodriver と同様に DevTools プロトコルを公開しているため、プロセス内で認証チャレンジをインターセプトできます: RequestPausedAuthRequired ハンドラを登録し、その後 Fetch ドメインを handle_auth_requests=True で有効にして continue_with_auth で応答します。2つの非明示的なルールは nodriver と同一です — ドメインを有効にする前にハンドラを追加し、asyncio.create_task で応答を発火させることで、待機がループをデッドロックさせないようにします。

import asyncio
import zendriver as zd

async def main():
    browser = await zd.start(browser_args=["--proxy-server=gate.quantumproxies.io:PORT"])
    tab = await browser.get("draft:,")            # blank tab first

    async def on_auth(event):
        asyncio.create_task(tab.send(zd.cdp.fetch.continue_with_auth(
            request_id=event.request_id,
            auth_challenge_response=zd.cdp.fetch.AuthChallengeResponse(
                response="ProvideCredentials", username="USER", password="PASS",
            ),
        )))

    async def on_request(event):
        asyncio.create_task(tab.send(
            zd.cdp.fetch.continue_request(request_id=event.request_id)))

    # handlers FIRST, then enable the domain
    tab.add_handler(zd.cdp.fetch.RequestPaused, on_request)
    tab.add_handler(zd.cdp.fetch.AuthRequired, on_auth)
    await tab.send(zd.cdp.fetch.enable(handle_auth_requests=True))

    page = await browser.get("https://httpbin.org/ip")
    await asyncio.sleep(3)
    print(await page.get_content())
    await browser.stop()

zd.loop().run_until_complete(main())

ハンドラの順序が重要な理由と、間違えた場合に何が起こるかの完全な説明は、私たちの nodriver プロキシ認証ガイド にあります — メカニクスは共有されているため、2回再現する理由はありません。

修正 3: プロキシ認証拡張と SOCKS5

問題 #10 が推奨するルートは生成された Chrome 拡張です: Manifest V3 マニフェストとプロキシを設定し chrome.webRequest.onAuthRequired に応答するワーカーを含み、--headless=new の下で --load-extension でロードします。これは SOCKS5 を含む任意のプロキシタイプを処理します。認証付き SOCKS5 はフラグを通じて決して機能しないためです — Chromium は SOCKS5 のユーザー名/パスワードサポートを持っていません (Chromium バグ 40829748)。SOCKS5 の代替は、認証情報を保持し、127.0.0.1 で認証なしのエンドポイントを提供するローカルリレーであり、プロキシリレーガイドで説明されています。すべての QuantumProxies プランは HTTP と SOCKS5 エンドポイント の両方を提供しているため、HTTP を使用することで問題を回避できることがよくあります。HTTP は Basic 認証をクリーンに処理します。

nodriver から実際に異なる点

フォークは見た目だけのものではありません。現代のアンチボットシステムに対抗して nodriver、zendriver、Selenium、Playwright を比較する公開ベンチマークでは、nodriver/zendriver ファミリーが最も強力で、zendriver は未マージの上流修正を持っているため、わずかに優れています。実際には、プロキシ作業に影響を与える違いは、問題がトリアージされるアクティブな問題トラッカー、より安定したリリースサイクル、セッションごとにスピンアップできる分離されたブラウザコンテキスト、そして nodriver から保持されたバッテリーを含む便利さです。それらは認証のギャップを閉じませんが、修正が行われたときにより速く到達し、zendriver が多くの並行セッションを実行するためのより簡単なフォークとなります。それらの同時コンテキスト間で出口を回転させたりプールしたりするために、プロキシプール管理に関する私たちのノートは、回転プロキシを通じてルートするか、ログインフローのために固定セッションをピンするかに関わらず、zendriver にそのまま適用されます。

一つの区別: docs.rs にも zendriver という名前の別の Rust クレートが存在します。これはここで議論されている Python フォークとは無関係です — もし Python でスクレイピングしているなら、pip install zendriver があなたが望むものです。

zendriver プロキシの認証フロー: インストール、プロキシフラグで開始、IP をホワイトリスト化、または CDP 認証ハンドラにフォールバック
出口 IP が安定している場合はホワイトリスト化し、そうでない場合は CDP チャレンジに応答します。user:pass フラグはどちらにしても行き止まりです。

よくある質問

zendriver でプロキシを使用するにはどうすればよいですか?

zendriver.start() を呼び出すときに browser_args を通じてアドレスを渡します: browser_args=["--proxy-server=host:port"]。これにより、認証されていないエンドポイントのプロキシを通じてすべてのトラフィックがルーティングされます。認証されたプロキシの場合、フラグに user:pass を入れることはできません — IP をホワイトリスト化するか、CDP Fetch.AuthRequired ハンドラを使用するか、プロキシ認証拡張をロードします。

zendriver は認証付きプロキシをサポートしていますか?

組み込みのパラメータを通じてではありません — ギャップは問題 #10 と #208 で追跡されています。Chromium はプロキシフラグの認証情報を無視するため、別の方法で認証します: プロバイダでの IP ホワイトリスト化、プロセス内でチャレンジに応答する CDP ハンドラ、生成された Chrome 拡張、または認証情報を保持するローカルリレーです。

nodriver と zendriver の違いは何ですか?

zendriver は nodriver のコミュニティが維持するフォークで、同じ CDP アーキテクチャ、ステルス目標、API を持っています。違いはメンテナンスにあります: zendriver は GitHub で問題とプルリクエストを受け入れ、未マージの上流バグ修正を提供し、より定期的にリリースされます。プロキシ認証は両方で同じように動作します — このガイドの修正はどちらにも適用されます。

zendriver は認証付き SOCKS5 プロキシを使用できますか?

フラグを介してはできません。なぜなら Chromium は SOCKS5 のユーザー名/パスワード認証を実装しておらず (Chromium バグ 40829748)、zendriver はそれを引き継いでいるからです。プロキシ認証拡張を使用するか、認証情報を追加するローカルリレーを実行するか、プロバイダの HTTP エンドポイントを zendriver に指示します — HTTP Basic プロキシ認証は SOCKS5 認証が機能しないところで信頼性があります。

zendriver は今日構築するための2つのフォークの中でより鋭いものですが、nodriver と同じ認証付きプロキシの問題を抱えています。IP が固定されている場合はホワイトリスト化し、そうでない場合は CDP チャレンジに応答し、拡張とリレーをフォールバックとして保持します。どちらを選んでも、出口 IP が重要な役割を果たします — 維持されたフォークでも、焼き尽くされたデータセンターアドレスではブロックされます。

zendriver にクリーンな住宅用出口を提供してください