Proxy Zendriver con Autenticación: Configuración y Soluciones

Zendriver es el fork mantenido por la comunidad de nodriver: más rápido para corregir, pero con la misma brecha de proxy autenticado. Aquí está la configuración completa del proxy, lo que realmente difiere y las soluciones que hacen que user:pass funcione.

Un proxy zendriver se configura exactamente como uno de nodriver, lo cual es tanto la buena noticia como el inconveniente. zendriver (el proyecto cdpdriver/zendriver) es el fork mantenido por la comunidad de nodriver: un marco de automatización de navegador asíncrono y no detectado que maneja Chrome directamente a través del DevTools Protocol, sin WebDriver a la vista. Existe porque el único mantenedor de nodriver rara vez fusionaba correcciones externas, por lo que la comunidad hizo un fork para aceptar correcciones de errores, agregar características y abordar problemas en GitHub. Lo que no corrigió son los proxies autenticados. Esta guía cubre la configuración completa del proxy, lo que realmente difiere de nodriver y las soluciones que hacen que user:pass funcione.

Instalación y configuración básica del proxy

La instalación es una línea — pip install zendriver — y la API refleja a nodriver casi símbolo por símbolo, por lo que import zendriver as zd es a menudo el único cambio al portar un script. Un proxy no autenticado pasa por browser_args, y la solicitud sale desde la IP del 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())

Eso funciona porque es solo una bandera de Chrome. Agrega credenciales — --proxy-server=http://USER:PASS@host:port — y Chromium descarta silenciosamente la parte USER:PASS@, el proxy responde 407, y aparece un cuadro de diálogo de inicio de sesión nativo que zendriver no puede completar. Esta es una limitación de Chrome, no un error de zendriver, por lo que ninguna actualización de versión hará que la bandera acepte una contraseña.

La brecha de autenticación de proxy de zendriver

La brecha se rastrea abiertamente en los problemas de zendriver: un hilo de solicitud de características (#10) y un problema dedicado "Proxy con auth" (#208), lo cual en sí mismo es una diferencia digna de notar: en nodriver la misma pregunta está enterrada en una discusión que el mantenedor respondió una vez y siguió adelante. Un usuario en el problema #10 resume el estado de las cosas de manera contundente: la opción del servidor proxy no tiene forma de autenticar, por lo que usan una extensión de proxy en su lugar y funciona bien. Ese es el consenso probado en el campo, y apunta directamente a las mismas tres soluciones en las que confían los usuarios de nodriver.

Solución 1: Lista blanca de IP (la más simple)

Si tu trabajo se ejecuta desde una máquina con una IP pública estable, omite las credenciales por completo. Registra la IP de salida en el panel de tu proveedor y la puerta de enlace te autentica por dirección de origen — el código de zendriver permanece como el fragmento simple --proxy-server anterior, sin lógica de autenticación. Cada plan de QuantumProxies admite la lista blanca de IP junto con user:pass, lo que lo convierte en la recomendación predeterminada siempre que tu IP sea fija. El único límite es que autentica una máquina, no un script, por lo que los ejecutores efímeros y los contenedores detrás de NAT necesitan uno de los dos métodos siguientes.

Comparación de nodriver y zendriver mostrando la arquitectura CDP compartida y la brecha de autenticación de proxy, pero diferentes modelos de mantenimiento
zendriver mantiene el sigilo y la API de nodriver mientras agrega un rastreador de problemas abierto — la brecha de autenticación de proxy, sin embargo, se hereda sin cambios.

Solución 2: responder al desafío sobre CDP

Debido a que zendriver expone el DevTools Protocol de la misma manera que nodriver, puedes interceptar el desafío de autenticación en proceso: registra los manejadores RequestPaused y AuthRequired, luego habilita el dominio Fetch con handle_auth_requests=True y responde con continue_with_auth. Las dos reglas no obvias son idénticas a nodriver — agrega los manejadores antes de habilitar el dominio, y dispara las respuestas con asyncio.create_task para que esperarlas no pueda bloquear el bucle:

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

La guía completa de por qué el orden de los manejadores importa, y qué sucede cuando te equivocas, está en nuestra guía de autenticación de proxy nodriver — la mecánica es compartida, por lo que no hay razón para reproducirlas dos veces.

Solución 3: una extensión de proxy-auth y SOCKS5

La ruta que respalda el problema #10 es una extensión de Chrome generada: un manifiesto Manifest V3 más un trabajador que configura el proxy y responde a chrome.webRequest.onAuthRequired, cargado con --load-extension bajo --headless=new. Maneja cualquier tipo de proxy, incluido SOCKS5, lo que importa porque el SOCKS5 autenticado nunca funciona a través de la bandera — Chromium no tiene soporte de nombre de usuario/contraseña para SOCKS5 (error de Chromium 40829748). La alternativa para SOCKS5 es un relé local que mantiene las credenciales y ofrece un endpoint sin autenticación en 127.0.0.1, cubierto en la guía de relé de proxy. Cada plan de QuantumProxies ofrece tanto endpoints HTTP como SOCKS5, por lo que a menudo puedes evitar todo el problema usando HTTP, que maneja la autenticación básica de manera limpia.

Lo que realmente difiere de nodriver

El fork no es cosmético. En los benchmarks públicos que enfrentan a nodriver, zendriver, Selenium y Playwright contra sistemas modernos anti-bot, la familia nodriver/zendriver fue la más fuerte para pasar, con zendriver superando gracias a las correcciones no fusionadas que lleva. Prácticamente, las diferencias que afectan el trabajo con proxies son: un rastreador de problemas activo donde los problemas se clasifican, un ritmo de lanzamiento más estable, contextos de navegador aislados que puedes iniciar por sesión, y comodidades incluidas mantenidas de nodriver. Nada de eso cierra la brecha de autenticación — pero significa que las soluciones llegan más rápido cuando lo hacen, y hace que zendriver sea el fork más fácil para ejecutar muchas sesiones paralelas. Para rotar y agrupar salidas a través de esos contextos concurrentes, nuestras notas sobre gestión de grupos de proxies se aplican a zendriver sin cambios, ya sea que enrutes a través de proxies rotativos o fijes sesiones pegajosas para flujos con inicio de sesión.

Una aclaración: un crate de Rust separado también llamado zendriver existe en docs.rs. No está relacionado con el fork de Python discutido aquí — si estás haciendo scraping en Python, pip install zendriver es el que deseas.

Flujo de autenticación de un proxy zendriver: instalar, iniciar con la bandera del proxy, listar blanca la IP, o recurrir a un manejador de autenticación CDP
Lista blanca cuando tu IP de salida es estable; responde al desafío CDP cuando no lo es. La bandera user:pass es un callejón sin salida de cualquier manera.

Preguntas frecuentes

¿Cómo uso un proxy con zendriver?

Pasa la dirección a través de browser_args cuando llamas a zendriver.start(): browser_args=["--proxy-server=host:port"]. Eso enruta todo el tráfico a través del proxy para un endpoint no autenticado. Para un proxy autenticado no puedes poner user:pass en la bandera — lista blanca tu IP, usa un manejador CDP Fetch.AuthRequired, o carga una extensión de proxy-auth.

¿Zendriver admite proxies autenticados?

No a través de un parámetro incorporado — la brecha se rastrea en los problemas #10 y #208. Chromium ignora las credenciales en la bandera del proxy, por lo que autenticas de otra manera: lista blanca de IP en el proveedor, un manejador CDP que responde al desafío en proceso, una extensión de Chrome generada, o un relé local que mantiene las credenciales por ti.

¿Cuál es la diferencia entre nodriver y zendriver?

Zendriver es un fork mantenido por la comunidad de nodriver con la misma arquitectura CDP, objetivos de sigilo y API. La diferencia es el mantenimiento: zendriver toma problemas y pull requests en GitHub, envía correcciones de errores no fusionadas, y lanza más regularmente. La autenticación de proxy se comporta de manera idéntica en ambos — las soluciones en esta guía funcionan para cualquiera.

¿Puede zendriver usar un proxy SOCKS5 autenticado?

No a través de la bandera, porque Chromium nunca implementó la autenticación de nombre de usuario/contraseña para SOCKS5 (error de Chromium 40829748), y zendriver hereda eso. Usa una extensión de proxy-auth, ejecuta un relé local que agregue las credenciales, o apunta zendriver al endpoint HTTP de tu proveedor en su lugar — la autenticación básica de proxy HTTP funciona de manera confiable donde la autenticación SOCKS5 no.

Zendriver es el más afilado de los dos forks para construir hoy, pero te entrega el mismo problema de proxy autenticado que nodriver. Lista blanca cuando tu IP es fija, responde al desafío CDP cuando no lo es, y mantén la extensión y el relé como alternativas. Cualquiera que elijas, la IP de salida hace el trabajo pesado — un fork mantenido en una dirección de centro de datos quemada aún se bloquea.

Dale a zendriver salidas residenciales limpias