Autenticación de Proxy en Selenium: 4 Configuraciones que Realmente Funcionan
Chrome muestra un diálogo de autenticación que Selenium no puede tocar, y el truco de credenciales en la URL falla silenciosamente. Aquí están las cuatro configuraciones que realmente autentican un proxy en Selenium, clasificadas por lo poco que te perjudicarán.
La autenticación de proxy en Selenium es una trampa disfrazada de una línea de código. La bandera --proxy-server de Chrome acepta felizmente una dirección de proxy, pero ignora silenciosamente cualquier nombre de usuario y contraseña que incluyas. Luego, Chrome muestra un diálogo de autenticación nativo que WebDriver no puede ver, tu script se cuelga, y la respuesta principal en Stack Overflow que encuentras (113+ votos) lo soluciona con una extensión Manifest V2 que Chrome moderno ya no carga. Esta guía cubre las cuatro configuraciones que autentican un proxy en Selenium hoy en día: lista blanca de IPs, una extensión Manifest V3, selenium-wire, y saber cuándo delegar todo el problema del navegador a una API.
Por qué falla la autenticación básica de proxy en Selenium
Tres hechos explican cada intento fallido. Primero, Chromium elimina las credenciales de --proxy-server=http://user:pass@host:port — el formato de la bandera simplemente no tiene soporte para credenciales. Segundo, el desafío 407 Proxy Authentication Required del proxy aparece como un diálogo nativo, fuera del DOM, donde send_keys no puede llegar. Tercero, la antigua ruta de DesiredCapabilities (socksUsername / socksPassword) solo se aplicaba a proxies SOCKS y nunca funcionó para los HTTP — la configuración que 'parece correcta' y no hace nada. Así que las opciones reales evitan el diálogo por completo.
Método 1: Lista blanca de IPs — cero código, cero diálogos
Si tu scraper se ejecuta desde una máquina con una IP pública estable, omite las credenciales por completo: registra esa IP en el panel de tu proveedor de proxy, y el gateway te autentica por dirección de origen. Cada plan de QuantumProxies admite la lista blanca de IPs junto con usuario:contraseña. El lado de Selenium se convierte en la bandera simple — que siempre ha funcionado bien sin autenticación:
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://gate.quantumproxies.io:PORT")
options.add_argument("--headless=new")
driver = webdriver.Chrome(options=options)
driver.get("https://httpbin.org/ip")
print(driver.find_element("tag name", "body").text) # proxy exit IP
driver.quit()
Siempre verifica la salida antes de confiar en una ejecución: carga un endpoint de eco de IP y confirma que la dirección pertenece al proxy, porque una bandera mal configurada falla silenciosamente y Chrome simplemente se conecta directamente. El límite de la lista blanca es topológico: autentica una máquina, no un script. Los runners en la nube efímeros, los contenedores detrás de NAT y las máquinas CI con IPs cambiantes necesitan uno de los métodos a continuación.
Método 2: una extensión de Chrome Manifest V3
La solución clásica genera una pequeña extensión de Chrome que configura el proxy y responde al desafío de autenticación a través de chrome.webRequest.onAuthRequired. El famoso fragmento de 2019 usa Manifest V2, que Chrome ha retirado ahora — la versión moderna necesita manifest_version: 3, un service worker, y el permiso webRequestAuthProvider. Esto construye y carga una en tiempo de ejecución:
import json, os, tempfile
from selenium import webdriver
HOST, PORT = "gate.quantumproxies.io", "PORT"
USER, PASS = "USER", "PASS"
manifest = {
"name": "Proxy Auth", "version": "1.0", "manifest_version": 3,
"permissions": ["proxy", "webRequest", "webRequestAuthProvider"],
"host_permissions": ["<all_urls>"],
"background": {"service_worker": "worker.js"},
}
worker = """
chrome.proxy.settings.set({
value: { mode: "fixed_servers", rules: {
singleProxy: { scheme: "http", host: "%s", port: parseInt("%s") },
bypassList: ["localhost"] } },
scope: "regular"
}, function() {});
chrome.webRequest.onAuthRequired.addListener(
function(details) {
return { authCredentials: { username: "%s", password: "%s" } };
},
{ urls: ["<all_urls>"] },
["blocking"]
);
""" % (HOST, PORT, USER, PASS)
ext_dir = tempfile.mkdtemp()
with open(os.path.join(ext_dir, "manifest.json"), "w") as f:
json.dump(manifest, f)
with open(os.path.join(ext_dir, "worker.js"), "w") as f:
f.write(worker)
options = webdriver.ChromeOptions()
options.add_argument("--load-extension=" + ext_dir)
options.add_argument("--headless=new")
driver = webdriver.Chrome(options=options)
driver.get("https://httpbin.org/ip")
Dos trampas. Las extensiones solo se cargan en el nuevo modo headless — el simple --headless falla con un críptico error de 'failed to wait for extension background page', por lo que --headless=new es obligatorio. Y cargar un directorio desempaquetado a través de --load-extension es más confiable en todas las versiones de Chrome que empaquetar un zip. Si prefieres no mantener esto, el paquete selenium-authenticated-proxy en PyPI genera la extensión por ti a partir de una sola URL de proxy.

Método 3: selenium-wire, y sus compensaciones
selenium-wire envuelve WebDriver con un proxy local man-in-the-middle, lo que hace que los proxies upstream autenticados — incluidos SOCKS5 — sean un simple diccionario de opciones:
# pip install selenium-wire
from seleniumwire import webdriver
options = {
"proxy": {
"http": "http://USER:PASS@gate.quantumproxies.io:PORT",
"https": "http://USER:PASS@gate.quantumproxies.io:PORT",
"no_proxy": "localhost,127.0.0.1",
}
}
driver = webdriver.Chrome(seleniumwire_options=options)
driver.get("https://httpbin.org/ip")
Sabe lo que estás comprando. El proyecto fue archivado por su mantenedor a principios de 2024 y no recibe actualizaciones, y porque descifra el tráfico localmente, el objetivo ve el apretón de manos TLS de selenium-wire en lugar del de Chrome — una discrepancia que los sistemas de huellas digitales JA3/JA4 marcan incluso cuando tu IP está impecable. Sigue siendo genuinamente útil para la inspección de solicitudes durante el desarrollo y para Firefox, donde el truco de la extensión no existe. Para scraping en producción en sitios protegidos, prefiere los métodos 1-2, o sube un nivel.
Firefox, y la brecha de autenticación
Firefox acepta un proxy no autenticado limpiamente a través de las preferencias de perfil (network.proxy.type = 1 más configuraciones de host y puerto), pero no tiene equivalente del truco de extensión de Chrome para responder al diálogo de credenciales desde WebDriver. En la práctica, los usuarios de Firefox eligen la lista blanca de IPs o selenium-wire. Si tu única razón para Firefox era su manejo de proxy, esa razón ya no es válida.
Cuándo dejar de parchear Selenium y cambiar a una API
La autenticación es el primer impuesto, no el último. Una instancia de Chrome cuesta cientos de MB de RAM, por lo que unas pocas docenas de sesiones concurrentes saturan un servidor; las versiones de ChromeDriver persiguen los lanzamientos de Chrome; y los proveedores de anti-bots detectan Selenium estándar independientemente de la IP detrás de él — navigator.webdriver y los artefactos de CDP lo delatan. Dos mejoras cambian la economía. Primero, ejecuta tus navegadores a través de proxies residenciales para que la reputación de IP deje de ser la razón por la que estás bloqueado — más de 90 millones de IPs domésticas con rotación por solicitud o sesiones persistentes para flujos con inicio de sesión. Segundo, cuando mantener navegadores deja de valer la pena, una Scraper API colapsa toda la pila en una sola llamada HTTP: renderiza JavaScript bajo demanda, gestiona IPs y reintentos internamente, y devuelve HTML, markdown o JSON estructurado. El mismo intercambio se aplica a los primos de Selenium — consulta nuestras guías sobre integración de proxy en Playwright y configuración de proxy en Puppeteer antes de asumir que un cambio de framework solucionará un problema de detección.

Preguntas frecuentes
¿Cómo configuro un proxy con autenticación en Selenium ChromeDriver?
O bien lista blanca la IP de tu máquina con el proveedor de proxy y pasa una simple bandera --proxy-server, o carga una pequeña extensión Manifest V3 que configura el proxy y proporciona credenciales a través de chrome.webRequest.onAuthRequired. Incrustar user:pass@ en la bandera no funciona — Chromium lo ignora.
¿Por qué Chrome muestra un popup de inicio de sesión de proxy con Selenium?
El proxy respondió con 407 y Chrome está pidiendo credenciales a un humano. El diálogo es una interfaz de usuario nativa, invisible para WebDriver, por lo que ningún selector o llamada send_keys puede llenarlo. La solución es autenticar antes de que el diálogo pueda aparecer: lista blanca de IPs, una extensión de autenticación, o una capa MITM como selenium-wire.
¿Sigue funcionando selenium-wire en 2026?
Todavía se instala y funciona para muchas cargas de trabajo, pero el proyecto fue archivado a principios de 2024 y no recibe mantenimiento. Su diseño MITM también reemplaza la huella digital TLS de Chrome con una de Python, que los sistemas modernos de anti-bots detectan. Trátalo como una herramienta de depuración, no como la base de un scraper de producción.
¿Cómo uso un proxy autenticado con Firefox en Selenium?
Las preferencias de perfil de Firefox configuran la dirección del proxy pero no pueden responder al aviso de credenciales, y no hay una solución de extensión como en Chrome. Usa la lista blanca de IPs para que no se necesiten credenciales, o enruta Firefox a través de selenium-wire, que maneja la autenticación upstream localmente.
¿Esto funciona igual en Java y C#?
Sí — la mecánica reside en Chrome, no en el enlace del lenguaje. La lista blanca de IPs más --proxy-server es idéntica en todas partes, y el enfoque de extensión Manifest V3 funciona desde Java o C# escribiendo los mismos dos archivos y agregando --load-extension a ChromeOptions. Solo selenium-wire es específico de Python; otros lenguajes sustituyen un proxy MITM local como BrowserMob.
La versión corta: nunca luches contra el diálogo de autenticación. Lista blanca cuando tu IP es estable, genera una extensión MV3 cuando no lo es, mantén selenium-wire para trabajos de inspección — y cuando el mantenimiento del navegador supere los datos que produce, promueve el trabajo a una API y disfruta de tus tardes.