Tu script de Selenium funciona, pero necesitas las páginas tal como las ve un visitante de Alemania, o la tarea tiene que correr desde un servidor al que el sitio ya le limita las peticiones. Añades un proxy y obtienes una página en blanco, sin ningún error. Casi siempre la causa es la contraseña: el estándar WebDriver no tiene ningún campo para las credenciales del proxy, así que user:pass@host:port se rechaza o se ignora sin avisar.
Esta guía cubre la configuración del proxy en Chrome, Edge y Firefox, los métodos de autenticación que funcionan hoy, SOCKS5, HTTPS, la rotación y los mensajes de error. Todos los ejemplos de Python se ejecutaron con Selenium 4.49, Chrome 154, Edge 153 y Firefox 156 en Windows 11, contra un proxy de prueba local que pide usuario y contraseña.
¿Qué es Selenium?
Selenium controla un navegador real desde el código. Se usa sobre todo para probar aplicaciones web, pero también para recoger datos de páginas que solo se generan con JavaScript. Abre páginas, hace clic, escribe texto, envía formularios y lee el contenido de la página como lo haría una persona. Tu código llama a la biblioteca de Selenium, la biblioteca habla con un driver (ChromeDriver, msedgedriver o geckodriver) y el driver controla el navegador mediante el protocolo W3C WebDriver.
Selenium admite Chrome, Edge, Firefox y Safari, con bibliotecas oficiales para Python, Java, C#, Ruby y JavaScript. Desde la versión 4.6 incluye Selenium Manager, que localiza el navegador instalado y descarga el driver que le corresponde. ¿Todavía estás eligiendo herramienta? Mira Playwright o Selenium: ¿cuál elegir en tu proyecto?.
¿Cómo funciona un proxy en Selenium?
En Selenium el proxy pertenece a la sesión del navegador, no a una petición concreta:
- Pones el proxy en las opciones del navegador, como el argumento de Chrome
--proxy-servero como un objetoProxy(la capacidadproxydel estándar WebDriver). - El driver arranca el navegador con esa configuración, que se aplica a todas las pestañas hasta
driver.quit(). - Para una página
https://, el navegador envíaCONNECT host:443al proxy y abre un túnel cifrado. Para una páginahttp://, envía la URL completa al proxy. - Si el proxy pide inicio de sesión, responde
407 Proxy Authentication Required. Este es el paso que el estándar WebDriver no cubre. - El sitio de destino ve la IP de salida del proxy. Para usar otro proxy, arrancas un navegador nuevo.
Chrome también envía su propio tráfico en segundo plano (actualizaciones, servicios de la cuenta) a través del proxy, y ese tráfico cuenta en un plan que se factura por gigabyte.
¿Cómo se usa Selenium con un proxy en Python?
Paso 1: instala Selenium. Selenium 4.49 necesita Python 3.10 o posterior:
pip install seleniumPaso 2: consigue un servidor proxy. Elige un producto en la página de proxies; el Generador de endpoints del panel de Proxynet te da la dirección del gateway, el puerto y un nombre de usuario que ya lleva el país, la ciudad y la sesión que elegiste. HTTP y SOCKS5 usan puertos distintos en el mismo gateway.
Paso 3: el WebDriver. Muchas guías antiguas dicen que hay que descargar ChromeDriver a mano y pasar executable_path. Ese parámetro ya no existe: desde Selenium 4.6, Selenium Manager descarga el driver adecuado en la primera ejecución, y la instalación manual solo hace falta en versiones anteriores. Si el equipo necesita un proxy para salir a internet, define SE_PROXY para las descargas de Selenium Manager.
Paso 4: arranca el navegador con el proxy. Para un proxy que no pide contraseña (con una lista de IP autorizadas, que vemos más abajo):
from selenium import webdriver
from selenium.webdriver.common.by import By
PROXY = "http://pr.proxynet.io:8000"
options = webdriver.ChromeOptions()
options.add_argument(f"--proxy-server={PROXY}")
options.add_argument("--headless") # quítalo para ver el navegador
driver = webdriver.Chrome(options=options)
try:
driver.get("https://api.ipify.org/?format=json")
print(driver.find_element(By.TAG_NAME, "body").text) # {"ip": "<IP de salida>"}
finally:
driver.quit()Sustituye el valor de PROXY por la dirección y el puerto de tu panel. La IP que se imprime debe ser la IP de salida del proxy. El objeto Proxy de Selenium hace el mismo trabajo (options.proxy = Proxy({"proxyType": ProxyType.MANUAL, "httpProxy": "host:port", "sslProxy": "host:port"})), y en nuestra prueba las dos formas enviaron el tráfico por el mismo camino.
¿Cómo se usa un proxy con usuario y contraseña en Selenium?
La definición de proxy del W3C WebDriver tiene claves para las direcciones del proxy, pero ninguna para el usuario o la contraseña, y la documentación de proxies de Chromium dice que Chrome no usa las credenciales incluidas en la configuración del proxy. Tampoco existe un argumento --proxy-auth, aunque aparece en mucho código antiguo. Estos son los resultados de nuestras pruebas contra un proxy que pide inicio de sesión:
| Qué probamos | Qué pasó |
|---|---|
--proxy-server=http://host:port, sin credenciales | El proxy devolvió 407; sin excepción, página en blanco |
--proxy-server=http://user:pass@host:port | Página de error ERR_NO_SUPPORTED_PROXIES, sin excepción |
user:pass@host:port en el objeto Proxy | La página cargó, pero Chrome se conectó directamente, desde nuestra propia IP |
Selenium BiDi driver.network.add_auth_handler(), Chrome | La respuesta al desafío falló con Invalid InterceptionId y después se agotó el tiempo de espera |
CDP Fetch.continueWithAuth (helper más abajo) | Funcionó en Chrome 154 y Edge 153 |
| Puerto sin inicio de sesión (lista de IP autorizadas) | Funcionó |
La tercera fila es la peligrosa: el script parece funcionar mientras el tráfico se salta el proxy.
Opción 1: lista de IP autorizadas
Añade la IP pública del equipo que ejecuta el script a la lista de IP autorizadas (whitelist) del proxy, y el proxy deja de pedir contraseña. El código del paso 4 funciona entonces sin cambios, igual que las versiones para Edge y Firefox. Proxynet admite hasta 10 IP. Encaja con un servidor de IP fija, no con un portátil cuya IP cambia; tienes más detalles en Autenticación de proxy: user:pass o lista blanca de IP.
Opción 2: responder al 407 con el Chrome DevTools Protocol
Chrome y Edge exponen el dominio Fetch del DevTools Protocol. Con handleAuthRequests activado, el navegador pausa cada petición que necesita credenciales y lanza Fetch.authRequired, cuyo source es Server o Proxy. El helper solo responde a los desafíos del proxy; websocket-client se instala junto con Selenium.
# proxy_auth.py
import json
import threading
import urllib.request
import websocket # se instala junto con selenium (websocket-client)
def attach_proxy_auth(driver, username, password):
"""Responde a los desafíos 407 del proxy en la pestaña mediante el Chrome DevTools Protocol."""
caps = driver.capabilities
vendor = caps.get("goog:chromeOptions") or caps.get("ms:edgeOptions") # Chrome o Edge
address = vendor["debuggerAddress"]
with urllib.request.urlopen(f"http://{address}/json") as resp:
targets = json.load(resp)
page = next(t for t in targets if t["type"] == "page")
ws = websocket.create_connection(page["webSocketDebuggerUrl"], suppress_origin=True)
counter = {"id": 0}
def send(method, params=None):
counter["id"] += 1
ws.send(json.dumps({"id": counter["id"], "method": method, "params": params or {}}))
def listen():
while True:
try:
msg = json.loads(ws.recv())
except Exception:
return # el navegador se cerró
method = msg.get("method")
params = msg.get("params", {})
if method == "Fetch.requestPaused":
send("Fetch.continueRequest", {"requestId": params["requestId"]})
elif method == "Fetch.authRequired":
if params["authChallenge"]["source"] == "Proxy":
answer = {"response": "ProvideCredentials",
"username": username, "password": password}
else:
answer = {"response": "Default"} # el inicio de sesión del propio sitio no nos toca responderlo
send("Fetch.continueWithAuth", {"requestId": params["requestId"],
"authChallengeResponse": answer})
send("Fetch.enable", {"handleAuthRequests": True})
while json.loads(ws.recv()).get("id") != counter["id"]:
pass # espera a que la interceptación esté activa antes del primer driver.get()
threading.Thread(target=listen, daemon=True).start()
return wsUsarlo cuesta una sola línea después de arrancar el driver:
from selenium import webdriver
from proxy_auth import attach_proxy_auth
options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://pr.proxynet.io:8000")
driver = webdriver.Chrome(options=options)
attach_proxy_auth(driver, "user", "pass")
driver.get("https://api.ipify.org/?format=json")Límites: el helper solo cubre la pestaña a la que se conectó, así que una ventana nueva arranca sin él. Con una contraseña incorrecta, Chrome muestra ERR_TOO_MANY_RETRIES.
¿Y Selenium Wire o las extensiones de proxy?
El repositorio de Selenium Wire se archivó el 3 de enero de 2024, y en un entorno limpio de Python 3.13 from seleniumwire import webdriver nos falló con ModuleNotFoundError: No module named 'pkg_resources'. Las extensiones de autenticación dependían del parámetro --load-extension, que las versiones oficiales de Chrome ignoran desde la 137; solo Chrome for Testing y Chromium lo siguen aceptando. SeleniumBase acepta proxy="user:pass@host:port" y gestiona el inicio de sesión por su cuenta; lo explicamos en Proxy con SeleniumBase: autenticación y rotación.
¿Qué método de proxy conviene usar en Selenium?
| Método | Chrome / Edge | Firefox | Contraseña | Estado en 2026 |
|---|---|---|---|---|
Argumento --proxy-server | Sí | No, usa preferencias | No | Vigente |
Objeto Proxy | Sí | Sí | Se ignora | Vigente |
| Lista de IP autorizadas | Sí | Sí | No hace falta | Vigente |
| Helper de CDP | Sí | No | Sí | Probado, funciona |
BiDi add_auth_handler | Falló en Chrome | Error con la ventana de inicio de sesión | En teoría | Aún no es fiable |
| Selenium Wire | Falla al importar | Falla al importar | Sí | Archivado |
| Extensión de autenticación | Solo Chrome for Testing | Formato aparte | Sí | Rota en Chrome 137+ |
¿Cómo se configura un proxy para Microsoft Edge en Selenium?
Edge está basado en Chromium, así que EdgeOptions acepta el mismo argumento, y Selenium Manager descarga msedgedriver:
from selenium import webdriver
options = webdriver.EdgeOptions()
options.add_argument("--proxy-server=http://pr.proxynet.io:8000")
driver = webdriver.Edge(options=options)El helper de CDP también funciona con Edge: con Edge 153 y el proxy de prueba protegido con contraseña, la página cargó a través del proxy.
¿Cómo se configura un proxy en Selenium con Firefox?
Firefox no lee --proxy-server. Define sus preferencias de red o pasa el objeto Proxy, que geckodriver convierte en esas mismas preferencias. Firefox no estaba instalado en nuestro equipo de prueba; Selenium Manager descargó Firefox 156 en la primera ejecución.
from selenium import webdriver
options = webdriver.FirefoxOptions()
options.set_preference("network.proxy.type", 1) # 1 = configuración manual
options.set_preference("network.proxy.http", "pr.proxynet.io")
options.set_preference("network.proxy.http_port", 8000)
options.set_preference("network.proxy.ssl", "pr.proxynet.io") # se usa para las páginas https://
options.set_preference("network.proxy.ssl_port", 8000)
driver = webdriver.Firefox(options=options)Para SOCKS5, define network.proxy.socks, network.proxy.socks_port y network.proxy.socks_version con el valor 5. Firefox envía entonces el nombre de dominio al proxy, porque network.proxy.socks5_remote_dns está activado por defecto; la preferencia antigua network.proxy.socks_remote_dns, que todavía aparece en muchos tutoriales, no cambió nada con SOCKS5 en Firefox 156, mientras que poner socks5_remote_dns en False hizo que Firefox resolviera los nombres en local. Firefox no tiene ninguna preferencia para las credenciales del proxy y el helper de CDP no se aplica a él. El add_auth_handler de BiDi en Selenium sí envió nuestras credenciales, pero la carga de la página falló igualmente con UnexpectedAlertPresentException por la ventana de inicio de sesión del proxy, así que usa una lista de IP autorizadas.
¿Puede Selenium usar un proxy SOCKS5?
Sí, sin contraseña: --proxy-server=socks5://host:port. En nuestra prueba, Chrome envió el nombre de dominio al proxy en lugar de resolverlo en local; la documentación de Chromium confirma que con SOCKS5 la resolución de nombres siempre ocurre en el lado del proxy.
Con contraseña, no: Chromium no admite autenticación SOCKS5, y driver.get() lanzó net::ERR_SOCKS_CONNECTION_FAILED. El helper de CDP no sirve aquí, porque SOCKS no tiene un 407 al que responder. Usa el puerto SOCKS5 con una lista de IP autorizadas, o el puerto HTTP con el helper. Tienes más información en ¿Qué es un proxy SOCKS5? y en Diferencia entre SOCKS y HTTP; los Proxies SOCKS5 de Proxynet funcionan en su propio puerto del mismo gateway.
¿Funciona Selenium con sitios HTTPS a través de un proxy?
Sí. La dirección del proxy mantiene el esquema http:// aunque todas las páginas sean https://: el navegador abre un túnel CONNECT y TLS va de extremo a extremo entre el navegador y el sitio, así que el proxy ve el nombre del host, pero no el contenido. Por eso un objeto Proxy necesita sslProxy además de httpProxy; solo con httpProxy, nuestras páginas https:// salieron directamente, sin pasar por el proxy.
Un esquema https:// en --proxy-server cifra además la conexión con el propio proxy; lo explicamos en la página de Proxies HTTPS.
¿Cómo se integran proxies con Selenium en Java?
Java usa el mismo objeto Proxy. Muchos ejemplos en Java ponen user:pass@ dentro de setHttpProxy; en nuestra prueba, eso hizo que Chrome se saltara el proxy, de modo que esta versión se basa en una lista de IP autorizadas: el usuario y la contraseña no van en la dirección del proxy. Tampoco hace falta System.setProperty("webdriver.chrome.driver", …), porque Selenium Manager encuentra el driver. Selenium 4 necesita Java 11 o posterior.
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class SeleniumProxyExample {
public static void main(String[] args) {
// Sin credenciales: la IP del equipo está en la lista de IP autorizadas del proxy
String proxyAddress = "pr.proxynet.io:8000";
Proxy proxy = new Proxy();
proxy.setHttpProxy(proxyAddress);
proxy.setSslProxy(proxyAddress);
ChromeOptions options = new ChromeOptions();
options.setProxy(proxy);
// Selenium Manager encuentra o descarga el ChromeDriver adecuado
WebDriver driver = new ChromeDriver(options);
try {
driver.get("https://api.ipify.org/?format=json");
System.out.println(driver.getPageSource());
} finally {
driver.quit();
}
}
}options.addArguments("--proxy-server=http://pr.proxynet.io:8000") es el equivalente del argumento de Python. Escribimos este ejemplo a partir de la documentación de Selenium y no lo ejecutamos, porque el equipo de prueba solo tiene Java 8.
¿Cómo se rotan proxies residenciales en Selenium?
El proxy queda fijo durante toda la vida de un navegador, así que rotar significa arrancar un navegador nuevo:
- Gateway rotativo. Con los Proxies rotativos, la IP de salida cambia en el lado del gateway y tu código mantiene una sola dirección. Las conexiones de una misma carga de página pueden salir desde IP distintas: no importa en un listado de productos, pero sí en un flujo de inicio de sesión.
- Sesiones fijas. Con los Proxies de sesión fija, la IP se mantiene entre 1 y 60 minutos. Da a cada navegador su propio nombre de usuario de sesión desde el Generador de endpoints: un navegador, una sesión, una IP de salida.
Los dos modos funcionan con los Proxies residenciales; más detalles en Qué es la rotación de IP y cómo funciona y en Cómo rotar proxies en Python: guía con código.
El origen de la dirección también influye en la tasa de éxito. Las IP residenciales encajan con los destinos que revisan el origen con más rigor; para descargas rápidas en sitios poco exigentes bastan los Proxies de centro de datos, y si un flujo de varios pasos no debe cambiar nunca de dirección, los Proxies ISP te dan una IP fija.
Ejemplo completo: navegadores en paralelo con reintentos
El script lee seis páginas de quotes.toscrape.com, un sitio de práctica que genera su contenido con JavaScript. Ejecuta tres instancias de Chrome a la vez, arranca un navegador nuevo en cada intento, bloquea las imágenes para ahorrar tráfico y repite los fallos temporales con esperas cada vez más largas. Los errores que un reintento no puede arreglar detienen la tarea en el acto, incluidos los que solo muestran la página de error de Chrome.
import random
import re
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from selenium import webdriver
from selenium.common.exceptions import TimeoutException, WebDriverException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from proxy_auth import attach_proxy_auth
PROXY_SERVER = "http://pr.proxynet.io:8000"
PROXY_USER = "user"
PROXY_PASS = "pass"
URLS = [f"https://quotes.toscrape.com/js/page/{n}/" for n in range(1, 7)]
WORKERS = 3 # navegadores abiertos a la vez
ATTEMPTS = 3
# Un reintento no arregla estos errores: revisa antes la dirección, el puerto y las credenciales
FATAL = ("ERR_PROXY_CONNECTION_FAILED", "ERR_NO_SUPPORTED_PROXIES",
"ERR_SOCKS_CONNECTION_FAILED", "ERR_TOO_MANY_RETRIES")
def new_driver():
options = webdriver.ChromeOptions()
options.add_argument(f"--proxy-server={PROXY_SERVER}")
options.add_argument("--headless")
# Sin imágenes: menos tráfico a través del proxy
options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
driver = webdriver.Chrome(options=options)
driver.set_page_load_timeout(30)
attach_proxy_auth(driver, PROXY_USER, PROXY_PASS)
return driver
def scrape(url):
for attempt in range(ATTEMPTS):
driver = new_driver() # un navegador nuevo, y una conexión nueva al proxy, en cada intento
try:
driver.get(url)
# Algunos errores de proxy abren la página de error de Chrome sin lanzar una excepción
if driver.execute_script("return document.body.className") == "neterror":
code = re.search(r"ERR_[A-Z_]+", driver.page_source)
raise WebDriverException(code.group(0) if code else "Chrome error page")
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "div.quote span.text"))
)
quotes = driver.find_elements(By.CSS_SELECTOR, "div.quote span.text")
return url, [q.text for q in quotes]
except (TimeoutException, WebDriverException) as exc:
if any(code in str(exc) for code in FATAL) or attempt == ATTEMPTS - 1:
raise
time.sleep(2**attempt + random.random()) # espera exponencial con jitter
finally:
driver.quit()
with ThreadPoolExecutor(max_workers=WORKERS) as pool:
futures = [pool.submit(scrape, url) for url in URLS]
for future in as_completed(futures):
try:
url, quotes = future.result()
print(f"{url}: {len(quotes)} quotes")
except Exception as exc:
print("failed:", str(exc).splitlines()[0])Las seis páginas devolvieron 10 citas cada una en unos 22 segundos; un puerto cerrado detuvo todas las tareas con net::ERR_PROXY_CONNECTION_FAILED, y una contraseña incorrecta, con ERR_TOO_MANY_RETRIES. Mantén bajo el número de navegadores en paralelo (WORKERS): cada uno es un Chrome completo, y demasiadas sesiones simultáneas acaban en 429 Too Many Requests.
¿Cómo compruebas que Selenium usa de verdad el proxy?
Abre una página que muestre tu IP, como api.ipify.org, en el navegador con proxy y compárala con tu propia IP; si coinciden, el tráfico se salta el proxy. Tu panel también debería mostrar tráfico. WebRTC todavía puede revelar la IP local; mira Fugas de WebRTC y DNS: qué son y cómo evitarlas. Tienes una rutina completa en ¿Funciona tu proxy? Cómo probar un proxy y una comprobación de una línea en la terminal en cURL con proxy.
Errores comunes de Selenium con proxy y cómo solucionarlos
Estos mensajes salen de nuestras pruebas. Los códigos de Chrome aparecen en la excepción (unknown error: net::ERR_…) o solo en la página de error.
| Mensaje | Causa | Solución |
|---|---|---|
Página en blanco, driver.title vacío, sin excepción | El proxy respondió 407 y no se enviaron credenciales | Autoriza la IP o usa el helper de CDP |
ERR_NO_SUPPORTED_PROXIES (página de error) | Credenciales dentro de --proxy-server | Quita user:pass@ del argumento |
net::ERR_PROXY_CONNECTION_FAILED | Nada escucha en ese host y puerto | Revisa la dirección, el puerto y el cortafuegos |
net::ERR_TUNNEL_CONNECTION_FAILED | El proxy no pudo abrir el túnel | Revisa el host de destino y después el proxy |
net::ERR_SOCKS_CONNECTION_FAILED | El proxy SOCKS5 pide contraseña | Puerto HTTP con el helper, o lista de IP autorizadas |
ERR_TOO_MANY_RETRIES (página de error) | El proxy rechazó las credenciales del helper | Vuelve a copiar el usuario y la contraseña |
TypeError: WebDriver.__init__() got an unexpected keyword argument 'executable_path' | Código de Selenium 3 | Quítalo; Selenium Manager encuentra el driver |
… unexpected keyword argument 'chrome_options' | Lo mismo, con un nombre más antiguo | Usa options= |
Timed out receiving message from renderer | Una carga de página no terminó nunca | Revisa el proxy y vuelve a intentarlo |
Los errores de conexión de los clientes HTTP de Python se explican línea por línea en Max Retries Exceeded With URL: qué es y cómo solucionarlo.
Casos de uso
- Seguimiento de precios en tiendas que dependen de JavaScript, desde el mercado en el que vendes: cómo seguir los precios de la competencia y seguimiento de precios con proxies.
- Localización y QA: cargar tu propio sitio desde varios países antes de un lanzamiento; mira pruebas de aplicaciones.
- Verificación de anuncios: comprobar tus anuncios en las regiones por las que pagas; mira verificación de anuncios.
- Recogida de datos de páginas que necesitan JavaScript: extracción de datos.
Un proxy cambia el origen de la petición, no lo que el sitio permite: lee su robots.txt y sus condiciones, mantén un ritmo de peticiones bajo y prefiere una API oficial cuando exista. Tampoco oculta la automatización: un navegador controlado por WebDriver informa navigator.webdriver como true, tal como exige el estándar.
Guía de decisión
| Necesidad | Recomendación |
|---|---|
| Servidor con IP fija | Lista de IP autorizadas + --proxy-server, sin contraseña en el código |
| Portátil o runner de CI con IP cambiante | Puerto HTTP + el helper de CDP |
| Firefox | Preferencias de red + lista de IP autorizadas |
| SOCKS5 | socks5:// en --proxy-server, solo con lista de IP autorizadas |
| Flujo de inicio de sesión o de pago | Sesión fija, un navegador por sesión |
| Muchas páginas independientes | Gateway rotativo |
| Un proxy distinto por página en un mismo navegador | El proxy por contexto de Playwright, mira Playwright con un proxy |
Preguntas frecuentes
¿Puede Selenium usar un proxy con usuario y contraseña?
No con las opciones estándar, que no tienen campos para credenciales. En Chrome y Edge, el helper de DevTools de este artículo responde al 407 del proxy; en cualquier navegador, una lista de IP autorizadas elimina la necesidad de contraseña.
¿Selenium Wire sigue funcionando en 2026?
Se archivó el 3 de enero de 2024, y en un entorno limpio de Python 3.13 ni siquiera llegó a importarse en nuestra prueba, porque depende de pkg_resources, que las versiones actuales de setuptools ya no incluyen. Usa el helper o una lista de IP autorizadas.
¿Cómo cambio el proxy sin reiniciar el navegador?
El proxy queda fijado al iniciar la sesión: llama a driver.quit() y arranca un driver nuevo. Para tener una IP nueva por página dentro de un mismo navegador, usa un gateway rotativo, o Playwright, que acepta un proxy por contexto.
¿Funciona un proxy en modo headless?
Sí. --proxy-server y el helper de CDP se comportan igual con y sin --headless; todos los ejemplos de este artículo se ejecutaron en modo headless.
¿Puedo usar un proxy SOCKS5 con autenticación en Selenium?
No en Chrome ni en Edge, que no admiten autenticación SOCKS5; Firefox 156 también ofreció a nuestro proxy solo el método sin contraseña. Usa SOCKS5 con una lista de IP autorizadas, o el puerto HTTP con contraseña.
¿Por qué el sitio sigue mostrando mi IP real?
Casi siempre porque el proxy nunca se aplicó: las credenciales dentro del objeto Proxy hacen que Chrome se conecte directamente, y un objeto Proxy sin sslProxy deja las páginas https:// sin proxy. Si la IP es correcta pero la ubicación no cuadra, comprueba si hay fugas de WebRTC.
En resumen
Selenium fija el proxy una vez por sesión del navegador: --proxy-server para Chrome y Edge, preferencias o el objeto Proxy para Firefox. Para la autenticación, usa una lista de IP autorizadas o, en Chrome y Edge, el helper de DevTools que responde al 407; Selenium Wire y las extensiones por línea de comandos son callejones sin salida. SOCKS5 solo funciona sin contraseña, y rotar significa un navegador por IP o por sesión. Cuando tengas la configuración lista, elige un plan en la página de proxies de Proxynet y toma los datos del gateway del Generador de endpoints.




