Zendriver Proxy z uwierzytelnianiem: Konfiguracja i obejścia

Zendriver to społecznościowo utrzymywana wersja nodriver — szybsza w naprawie, ale z tym samym problemem z uwierzytelnianiem proxy. Oto pełna konfiguracja proxy, co faktycznie się różni i obejścia, które sprawiają, że user:pass działa.

zendriver proxy jest skonfigurowany dokładnie tak samo jak nodriver — co jest zarówno dobrą wiadomością, jak i pułapką. zendriver (projekt cdpdriver/zendriver) to społecznościowo utrzymywana wersja nodriver: asynchroniczne, niewykrywalne narzędzie do automatyzacji przeglądarki, które prowadzi Chrome bezpośrednio przez DevTools Protocol, bez WebDrivera na horyzoncie. Istnieje, ponieważ jedyny opiekun nodriver rzadko wprowadzał zewnętrzne poprawki, więc społeczność stworzyła fork, aby akceptować poprawki błędów, dodawać funkcje i rozwiązywać problemy na GitHub. Co nie zostało naprawione, to uwierzytelniane proxy. Ten przewodnik obejmuje pełną konfigurację proxy, co faktycznie różni się od nodriver i obejścia, które sprawiają, że user:pass działa.

Instalacja i podstawowa konfiguracja proxy

Instalacja to jedna linia — pip install zendriver — a API jest niemal identyczne z nodriver, więc import zendriver as zd jest często jedyną zmianą przy przenoszeniu skryptu. Nieautoryzowane proxy przechodzi przez browser_args, a żądanie wychodzi z IP proxy:

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())

To działa, ponieważ to tylko flaga Chrome. Dodaj dane uwierzytelniające — --proxy-server=http://USER:PASS@host:port — a Chromium cicho odrzuca część USER:PASS@, proxy odpowiada 407, i pojawia się natywne okno logowania, którego zendriver nie może wypełnić. To ograniczenie Chrome, a nie błąd zendriver, więc żadna aktualizacja nie sprawi, że flaga zaakceptuje hasło.

Luka w uwierzytelnianiu proxy zendriver

Luka jest otwarcie śledzona w problemach zendriver — wątek z prośbą o funkcję (#10) i dedykowany problem "Proxy z auth" (#208) — co samo w sobie jest różnicą wartą zauważenia: w nodriver to samo pytanie jest ukryte w dyskusji, na którą opiekun odpowiedział raz i poszedł dalej. Jeden z użytkowników w problemie #10 podsumowuje sytuację brutalnie: opcja serwera proxy nie ma sposobu na uwierzytelnienie, więc używają rozszerzenia proxy i działa to dobrze. To przetestowany konsensus, który wskazuje na te same trzy poprawki, na których polegają użytkownicy nodriver.

Naprawa 1: biała lista IP (najprostsza)

Jeśli Twoja praca działa z maszyny z stabilnym publicznym IP, pomiń całkowicie dane uwierzytelniające. Zarejestruj IP wyjściowe w panelu dostawcy, a brama uwierzytelnia Cię przez adres źródłowy — kod zendriver pozostaje prostym fragmentem --proxy-server powyżej, bez logiki uwierzytelniania. Każdy plan QuantumProxies obsługuje białą listę IP obok user:pass, co czyni ją domyślną rekomendacją, gdy Twoje IP jest stałe. Jedynym ograniczeniem jest to, że uwierzytelnia maszynę, a nie skrypt, więc efemeryczne uruchomienia i kontenery za NAT potrzebują jednej z dwóch następnych metod.

Porównanie nodriver i zendriver pokazujące wspólną architekturę CDP i lukę w uwierzytelnianiu proxy, ale różne modele utrzymania
zendriver zachowuje niewykrywalność i API nodriver, jednocześnie dodając otwarty tracker problemów — luka w uwierzytelnianiu proxy jednak pozostaje niezmieniona.

Naprawa 2: odpowiedz na wyzwanie przez CDP

Ponieważ zendriver udostępnia DevTools Protocol w ten sam sposób co nodriver, możesz przechwycić wyzwanie uwierzytelniające w procesie: zarejestruj obsługiwacze RequestPaused i AuthRequired, następnie włącz domenę Fetch z handle_auth_requests=True i odpowiedz z continue_with_auth. Dwie nieoczywiste zasady są identyczne jak w nodriver — dodaj obsługiwacze przed włączeniem domeny i uruchom odpowiedzi z asyncio.create_task, aby oczekiwanie na nie nie zablokowało pętli:

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())

Pełne omówienie, dlaczego kolejność obsługiwaczy ma znaczenie i co się dzieje, gdy popełnisz błąd, znajduje się w naszym przewodniku po uwierzytelnianiu proxy nodriver — mechanika jest wspólna, więc nie ma potrzeby ich powielać.

Naprawa 3: rozszerzenie proxy-auth i SOCKS5

Ścieżka, którą popiera problem #10, to wygenerowane rozszerzenie Chrome: manifest Manifest V3 plus pracownik, który ustawia proxy i odpowiada na chrome.webRequest.onAuthRequired, ładowane z --load-extension pod --headless=new. Obsługuje każdy typ proxy, w tym SOCKS5, co ma znaczenie, ponieważ uwierzytelnianie SOCKS5 nigdy nie działa przez flagę — Chromium nie obsługuje nazwy użytkownika/hasła dla SOCKS5 (błąd Chromium 40829748). Alternatywą dla SOCKS5 jest lokalny przekaźnik, który przechowuje dane uwierzytelniające i oferuje punkt końcowy bez uwierzytelniania na 127.0.0.1, omówiony w przewodniku po przekaźniku proxy. Każdy plan QuantumProxies oferuje zarówno punkty końcowe HTTP, jak i SOCKS5, więc często można ominąć cały problem, używając HTTP, które obsługuje uwierzytelnianie Basic bez problemu.

Co faktycznie różni się od nodriver

Fork nie jest kosmetyczny. W publicznych testach porównawczych zestawiających nodriver, zendriver, Selenium i Playwright z nowoczesnymi systemami anty-botowymi, rodzina nodriver/zendriver była najsilniejsza w przechodzeniu, z zendriver na czele dzięki niepołączonym poprawkom upstream, które posiada. Praktycznie, różnice wpływające na pracę z proxy to: aktywny tracker problemów, gdzie problemy są rozwiązywane, bardziej stabilny cykl wydawniczy, izolowane konteksty przeglądarki, które można uruchamiać na sesję, i wygody wbudowane z nodriver. Żadne z tego nie zamyka luki w uwierzytelnianiu — ale oznacza, że poprawki pojawiają się szybciej, gdy już to robią, i sprawia, że zendriver jest łatwiejszym forkiem do uruchamiania wielu równoległych sesji. Dla rotacji i puli wyjść w tych równoczesnych kontekstach, nasze notatki na temat zarządzania pulą proxy mają zastosowanie do zendriver bez zmian, niezależnie od tego, czy kierujesz przez rotujące proxy, czy przypinasz sesje dla zalogowanych przepływów.

Jedno wyjaśnienie: istnieje osobna biblioteka Rust również nazwana zendriver na docs.rs. Nie jest związana z omawianym tutaj forkiem Python — jeśli skrobiesz w Pythonie, pip install zendriver to ten, którego potrzebujesz.

Przepływ uwierzytelniania proxy zendriver: instalacja, uruchomienie z flagą proxy, biała lista IP lub powrót do obsługiwacza CDP auth
Biała lista, gdy Twoje IP wyjściowe jest stabilne; odpowiedz na wyzwanie CDP, gdy nie jest. Flaga user:pass to ślepa uliczka w obu przypadkach.

Najczęściej zadawane pytania

Jak używać proxy z zendriver?

Przekaż adres przez browser_args, gdy wywołujesz zendriver.start(): browser_args=["--proxy-server=host:port"]. To kieruje cały ruch przez proxy dla punktu końcowego bez uwierzytelnienia. Dla uwierzytelnianego proxy nie możesz umieścić user:pass we fladze — biała lista Twojego IP, użyj obsługiwacza CDP Fetch.AuthRequired lub załaduj rozszerzenie proxy-auth.

Czy zendriver obsługuje uwierzytelniane proxy?

Nie przez wbudowany parametr — luka jest śledzona w problemach #10 i #208. Chromium ignoruje dane uwierzytelniające we fladze proxy, więc uwierzytelniasz się w inny sposób: biała lista IP u dostawcy, obsługiwacz CDP, który odpowiada na wyzwanie w procesie, wygenerowane rozszerzenie Chrome lub lokalny przekaźnik, który przechowuje dane uwierzytelniające dla Ciebie.

Jaka jest różnica między nodriver a zendriver?

zendriver to społecznościowo utrzymywana wersja nodriver z tą samą architekturą CDP, celami niewykrywalności i API. Różnica to utrzymanie: zendriver przyjmuje problemy i pull requesty na GitHub, dostarcza niepołączone poprawki upstream i wydaje się bardziej regularnie. Uwierzytelnianie proxy działa identycznie w obu — poprawki w tym przewodniku działają dla obu.

Czy zendriver może używać uwierzytelnianego proxy SOCKS5?

Nie przez flagę, ponieważ Chromium nigdy nie zaimplementowało uwierzytelniania nazwa użytkownika/hasło dla SOCKS5 (błąd Chromium 40829748), a zendriver to dziedziczy. Użyj rozszerzenia proxy-auth, uruchom lokalny przekaźnik, który dodaje dane uwierzytelniające, lub skieruj zendriver na punkt końcowy HTTP dostawcy — uwierzytelnianie proxy HTTP Basic działa niezawodnie tam, gdzie uwierzytelnianie SOCKS5 nie działa.

zendriver jest ostrzejszym z dwóch forków do budowania dzisiaj, ale daje Ci ten sam problem z uwierzytelnianiem proxy, co nodriver. Biała lista, gdy Twoje IP jest stałe, odpowiedz na wyzwanie CDP, gdy nie jest, i trzymaj rozszerzenie i przekaźnik jako opcje awaryjne. Niezależnie od wyboru, IP wyjściowe wykonuje ciężką pracę — utrzymywany fork na spalonym adresie centrum danych nadal jest blokowany.

Daj zendriver czyste wyjścia rezydencjalne