Autenticación de proxy en Selenium y Playwright: todos los métodos que funcionan (2026)

Publicado el 4 de junio de 2026 · ≈10 min de lectura

Esta es la trampa en la que cae exactamente una vez todo desarrollador de automatización de navegadores: añades --proxy-server=http://user:pass@host:port a las flags de lanzamiento de Chrome, el navegador arranca bien, y luego cada página se queda colgada en un popup de autenticación que tu script no puede ver ni pulsar. Chrome elimina silenciosamente las credenciales de la flag del proxy. Sin error, sin línea de log, solo un diálogo modal en un navegador que nadie está mirando.

Esta guía es el mapa completo de los métodos de autenticación de proxy que de verdad funcionan en Selenium y Playwright en 2026 — cuál usar, cuál evitar, y el código exacto para cada uno. (Para la selección de proxies y la estrategia de rotación en estas herramientas, consulta Usar proxies con Playwright & Puppeteer — este artículo trata puramente sobre hacer que las credenciales pasen.)

Por qué user:pass@host falla en los navegadores

Los clientes HTTP de línea de comandos parsean las credenciales de las URL de proxy y responden al 407 Proxy Authentication Required del proxy con una cabecera Proxy-Authorization automáticamente. Chromium no: --proxy-server solo acepta scheme://host:port, y cuando vuelve el 407 muestra un diálogo interactivo. En modo headless ni siquiera hay diálogo — la petición simplemente falla.

Así que la pregunta nunca es "cómo pongo la contraseña en la URL" — es "qué capa responde al 407 por mí". Cuatro respuestas que funcionan, la mejor primero.

Método 1: autenticación nativa de Playwright (úsalo si puedes)

Playwright resolvió el problema correctamente: responde por sí mismo a los desafíos de autenticación de proxy mediante CDP. Las credenciales van en las opciones de lanzamiento o de contexto:

# Python
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(
        proxy={
            "server": "http://us.jibaoproxy.com:913",
            "username": "USERNAME-session-job1",
            "password": "PASSWORD",
        }
    )
// Node.js - and per-context, which is where it gets powerful:
const browser = await chromium.launch({
  proxy: { server: 'per-context' }   // declare intent at launch
});
const ctx = await browser.newContext({
  proxy: {
    server: 'http://us.jibaoproxy.com:913',
    username: 'USERNAME-session-job2',
    password: 'PASSWORD',
  }
});

Los proxies por contexto significan que un solo proceso de navegador puede ejecutar N contextos sobre N sesiones sticky distintas — el cimiento de toda configuración seria de scraping con Playwright. Si estás en Playwright, ya terminaste; salta a la sección de verificación. Todo lo de abajo existe porque Selenium no tiene equivalente.

Método 2: selenium-wire (Selenium, Python)

selenium-wire envuelve Selenium con un proxy MITM local que gestiona la autenticación ascendente:

from seleniumwire import webdriver   # pip install selenium-wire

options = {
    "proxy": {
        "http":  "http://USERNAME:[email protected]:913",
        "https": "https://USERNAME:[email protected]:913",
    }
}
driver = webdriver.Chrome(seleniumwire_options=options)
driver.get("https://example.com")

Advertencias que deberías conocer antes de producción:

Método 3: extensión de Chrome que inyecta credenciales (Selenium, cualquier lenguaje)

El enfoque clásico: una pequeña extensión generada que configura el proxy y responde a la autenticación mediante chrome.webRequest.onAuthRequired. Sin MITM, sin proceso extra, funciona en Selenium puro:

import zipfile, json

HOST, PORT = "us.jibaoproxy.com", 913
USER, PASS = "USERNAME-session-sel1", "PASSWORD"

manifest = {
    "version": "1.0.0", "manifest_version": 2, "name": "Proxy Auth",
    "permissions": ["proxy", "webRequest", "webRequestBlocking", ""],
    "background": {"scripts": ["background.js"]},
}
background = f"""
chrome.proxy.settings.set({{value: {{mode: "fixed_servers", rules: {{
  singleProxy: {{scheme: "http", host: "{HOST}", port: {PORT}}}
}}}}, scope: "regular"}}, () => {{}});
chrome.webRequest.onAuthRequired.addListener(
  () => ({{authCredentials: {{username: "{USER}", password: "{PASS}"}}}}),
  {{urls: [""]}}, ["blocking"]
);
"""

with zipfile.ZipFile("proxy_auth.zip", "w") as zp:
    zp.writestr("manifest.json", json.dumps(manifest))
    zp.writestr("background.js", background)

from selenium import webdriver
opts = webdriver.ChromeOptions()
opts.add_extension("proxy_auth.zip")
driver = webdriver.Chrome(options=opts)

Dos trampas: las extensiones no se cargan en el modo headless clásico — usa --headless=new (Chrome 109+) o ejecuta en modo headed; y los scripts de fondo de Manifest V2 todavía funcionan para extensiones de automatización cargadas de forma lateral, pero vigila el calendario de obsolescencia de MV2 de Chrome — el equivalente en MV3 necesita un service worker y el mismo listener onAuthRequired.

Método 4: reenviador local (el respaldo universal)

Ejecuta un pequeño proxy local que guarde las credenciales; apunta el navegador a localhost sin autenticación alguna. Funciona con todos los navegadores, todos los drivers, todos los lenguajes, headless o no:

# Using pproxy (pip install pproxy) - terminal 1:
pproxy -l http://127.0.0.1:8899 \
       -r "http://USERNAME:[email protected]:913"

# Your script - terminal 2: plain Selenium, no auth needed
opts = webdriver.ChromeOptions()
opts.add_argument("--proxy-server=http://127.0.0.1:8899")
driver = webdriver.Chrome(options=opts)

Esta es también la respuesta más limpia para Firefox/geckodriver (donde el truco de la extensión no aplica) y para entornos exóticos como las pruebas de apps Electron. Coste: una pieza móvil más que supervisar, y el enrutamiento por contexto requiere un puerto de reenviador por sesión.

Comparación de métodos

MétodoFunciona enHeadlessSesiones por contextoVeredicto de producción
Nativo de PlaywrightPlaywrightOpción por defecto
selenium-wireSelenium (Py)Por driverBien a escala moderada
Extensión de autenticaciónSelenium (cualquier lenguaje)Solo --headless=newPor driverSólido, vigila MV3
Reenviador localTodoUn puerto por sesiónRespaldo universal

Verifica que de verdad funcionó

El retroceso silencioso a tu IP real es el modo de fallo que hace que banean cuentas. Asegura la IP de salida al inicio de cada ejecución:

ip = driver.execute_script(
    "return fetch('https://api.ipify.org').then(r => r.text())"
) if hasattr(driver, 'execute_script') else page.evaluate(
    "fetch('https://api.ipify.org').then(r => r.text())"
)
assert ip != MY_REAL_IP, "Proxy not applied - aborting before we leak"
Herramienta gratuita · sin registro

Comprueba a ojo tu navegador automatizado

Lleva tu navegador de Selenium/Playwright a nuestra página What Is My IP: muestra la IP de salida, la geolocalización, el tipo de ASN y los indicadores de proxy/VPN en una sola vista — confirmación instantánea de que la capa de autenticación funcionó y la IP es residencial.

Abrir verificador de IP →

¿Ves un ASN de centro de datos en un proxy "residencial"? Cambia a un pool que sea de verdad residencial — 500MB de tráfico gratis →

Referencia rápida de resolución de problemas

Resumen

Los navegadores no leen las URL de proxy user:pass@ — algo tiene que responder al 407 por ellos. En Playwright ese algo está integrado; en Selenium es selenium-wire, una extensión de autenticación generada o un reenviador local. Elige según tu stack a partir de la tabla comparativa, y luego asegura la IP de salida en cada ejecución para que un fallo silencioso de autenticación nunca pueda filtrar tu dirección real a mitad del crawl.

Prueba los cuatro métodos esta noche

500MB de tráfico gratis — una puerta de enlace, sticky o rotativa, HTTP y SOCKS5.

Comenzar prueba gratuita

Para todos los productos IP · un enorme pool de nodos disponibles en cualquier momento

Regístrate ahora y obtén hasta un 100% de reembolso en tu recarga

Los nuevos usuarios reciben 500MB al registrarse, más un bono en la primera recarga. Oferta por tiempo limitado.