Proxy Zendriver Com Autenticação: Configuração e Soluções

Zendriver é o fork mantido pela comunidade do nodriver — mais rápido para corrigir, mas com a mesma lacuna de proxy autenticado. Aqui está a configuração completa do proxy, o que realmente difere e as soluções que fazem user:pass funcionar.

Um proxy zendriver é configurado exatamente como um do nodriver — o que é tanto a boa notícia quanto o problema. zendriver (o projeto cdpdriver/zendriver) é o fork mantido pela comunidade do nodriver: um framework de automação de navegador assíncrono e indetectável que dirige o Chrome diretamente pelo DevTools Protocol, sem WebDriver à vista. Ele existe porque o único mantenedor do nodriver raramente mesclava correções externas, então a comunidade fez um fork para aceitar correções de bugs, adicionar recursos e tratar problemas no GitHub. O que não foi corrigido são os proxies autenticados. Este guia cobre a configuração completa do proxy, o que realmente difere do nodriver, e as soluções que fazem user:pass funcionar.

Instalação e configuração básica do proxy

A instalação é uma linha — pip install zendriver — e a API espelha o nodriver quase símbolo por símbolo, então import zendriver as zd é frequentemente a única mudança ao portar um script. Um proxy não autenticado passa por browser_args, e a solicitação sai do IP do 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())

Isso funciona porque é apenas uma flag do Chrome. Adicione credenciais — --proxy-server=http://USER:PASS@host:port — e o Chromium descarta silenciosamente a parte USER:PASS@, o proxy responde 407, e um diálogo de login nativo aparece que o zendriver não pode preencher. Esta é uma limitação do Chrome, não um bug do zendriver, então nenhuma atualização de versão fará a flag aceitar uma senha.

A lacuna de autenticação de proxy do zendriver

A lacuna é abertamente rastreada nos problemas do zendriver — um tópico de solicitação de recurso (#10) e um problema dedicado "Proxy com auth" (#208) — que por si só é uma diferença digna de nota: no nodriver a mesma questão está enterrada em uma discussão que o mantenedor respondeu uma vez e seguiu em frente. Um usuário no problema #10 resume o estado de forma direta: a opção de servidor proxy não tem como autenticar, então eles usam uma extensão de proxy em vez disso e funciona bem. Esse é o consenso testado em campo, e aponta diretamente para as mesmas três correções em que os usuários do nodriver confiam.

Correção 1: Lista branca de IPs (a mais simples)

Se o seu trabalho é executado a partir de uma máquina com um IP público estável, ignore as credenciais completamente. Registre o IP de saída no painel do seu provedor e o gateway autentica você pelo endereço de origem — o código zendriver permanece o trecho simples --proxy-server acima, sem lógica de autenticação. Todo plano QuantumProxies suporta lista branca de IPs juntamente com user:pass, o que o torna a recomendação padrão sempre que seu IP é fixo. O único limite é que ele autentica uma máquina, não um script, então runners efêmeros e contêineres atrás de NAT precisam de um dos dois métodos seguintes.

Comparação de nodriver e zendriver mostrando arquitetura CDP compartilhada e lacuna de autenticação de proxy, mas diferentes modelos de manutenção
zendriver mantém a discrição e API do nodriver enquanto adiciona um rastreador de problemas aberto — a lacuna de autenticação de proxy, no entanto, é herdada sem alterações.

Correção 2: responder ao desafio sobre CDP

Porque zendriver expõe o DevTools Protocol da mesma forma que o nodriver, você pode interceptar o desafio de autenticação em processo: registre manipuladores RequestPaused e AuthRequired, depois habilite o domínio Fetch com handle_auth_requests=True e responda com continue_with_auth. As duas regras não óbvias são idênticas ao nodriver — adicione os manipuladores antes de habilitar o domínio, e dispare respostas com asyncio.create_task para que aguardá-las não possa bloquear o loop:

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

O passo a passo completo de por que a ordem dos manipuladores importa, e o que acontece quando você erra, está em nosso guia de autenticação de proxy nodriver — as mecânicas são compartilhadas, então não há razão para reproduzi-las duas vezes.

Correção 3: uma extensão de proxy-auth e SOCKS5

A rota que o problema #10 endossa é uma extensão Chrome gerada: um manifesto Manifest V3 mais um worker que define o proxy e responde chrome.webRequest.onAuthRequired, carregado com --load-extension sob --headless=new. Ele lida com qualquer tipo de proxy, incluindo SOCKS5, o que importa porque SOCKS5 autenticado nunca funciona através da flag — o Chromium não tem suporte para nome de usuário/senha para SOCKS5 (bug do Chromium 40829748). A alternativa para SOCKS5 é um relay local que mantém as credenciais e oferece um endpoint sem autenticação em 127.0.0.1, coberto no guia de relay de proxy. Todo plano QuantumProxies oferece endpoints HTTP e SOCKS5, então você pode frequentemente contornar todo o problema usando HTTP, que lida com autenticação Basic de forma limpa.

O que realmente difere do nodriver

O fork não é cosmético. Em benchmarks públicos colocando nodriver, zendriver, Selenium e Playwright contra sistemas modernos anti-bot, a família nodriver/zendriver foi a mais forte em passar, com zendriver à frente graças a correções upstream não mescladas que carrega. Praticamente, as diferenças que afetam o trabalho com proxy são: um rastreador de problemas ativo onde os problemas são triados, uma cadência de lançamento mais estável, contextos de navegador isolados que você pode criar por sessão, e conveniências incluídas mantidas do nodriver. Nada disso fecha a lacuna de autenticação — mas significa que as correções chegam mais rápido quando chegam, e torna o zendriver o fork mais fácil para executar muitas sessões paralelas. Para rotação e agrupamento de saídas nesses contextos concorrentes, nossas notas sobre gerenciamento de pool de proxy se aplicam ao zendriver sem alterações, seja você roteando através de proxies rotativos ou fixando sessões persistentes para fluxos logados.

Uma desambiguação: um crate Rust separado também chamado zendriver existe no docs.rs. Ele não está relacionado ao fork Python discutido aqui — se você está fazendo scraping em Python, pip install zendriver é o que você quer.

Fluxo de autenticação de um proxy zendriver: instalar, iniciar com a flag de proxy, listar o IP, ou recorrer a um manipulador de autenticação CDP
Liste quando seu IP de saída for estável; responda ao desafio CDP quando não for. A flag user:pass é um beco sem saída de qualquer forma.

Perguntas frequentes

Como uso um proxy com zendriver?

Passe o endereço através de browser_args quando você chamar zendriver.start(): browser_args=["--proxy-server=host:port"]. Isso roteia todo o tráfego através do proxy para um endpoint não autenticado. Para um proxy autenticado você não pode colocar user:pass na flag — liste seu IP, use um manipulador CDP Fetch.AuthRequired, ou carregue uma extensão de proxy-auth.

O zendriver suporta proxies autenticados?

Não através de um parâmetro embutido — a lacuna é rastreada nos problemas #10 e #208. O Chromium ignora credenciais na flag de proxy, então você autentica de outra forma: lista branca de IP no provedor, um manipulador CDP que responde ao desafio em processo, uma extensão Chrome gerada, ou um relay local que mantém as credenciais para você.

Qual é a diferença entre nodriver e zendriver?

zendriver é um fork mantido pela comunidade do nodriver com a mesma arquitetura CDP, objetivos de discrição e API. A diferença é a manutenção: zendriver aceita problemas e pull requests no GitHub, envia correções de bugs upstream não mescladas, e lança mais regularmente. A autenticação de proxy se comporta de forma idêntica em ambos — as correções neste guia funcionam para qualquer um.

O zendriver pode usar um proxy SOCKS5 autenticado?

Não via flag, porque o Chromium nunca implementou autenticação de nome de usuário/senha para SOCKS5 (bug do Chromium 40829748), e o zendriver herda isso. Use uma extensão de proxy-auth, execute um relay local que adicione as credenciais, ou aponte o zendriver para o endpoint HTTP do seu provedor — a autenticação de proxy HTTP Basic funciona de forma confiável onde a autenticação SOCKS5 não funciona.

zendriver é o mais afiado dos dois forks para construir hoje, mas ele entrega o mesmo problema de proxy autenticado que o nodriver faz. Liste quando seu IP for fixo, responda ao desafio CDP quando não for, e mantenha a extensão e o relay como alternativas. Qualquer que seja a escolha, o IP de saída faz o trabalho pesado — um fork mantido em um endereço de datacenter queimado ainda é bloqueado.

Dê ao zendriver saídas residenciais limpas