---
title: "Selenium con proxy en Python: Chrome, Edge, auth y SOCKS5"
description: "Para usar un proxy en Selenium, pasa --proxy-server en ChromeOptions o EdgeOptions. Explicamos user:pass con CDP, SOCKS5, Firefox, Java y la rotación."
url: https://proxynet.io/es/blog/selenium
date: 2024-04-23
updated: 2026-09-25
author: "PXNET"
category: "Integración"
lang: es
---

# Selenium con proxy en Python: Chrome, Edge, auth y SOCKS5

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.

> **Nota: Respuesta breve**
>
> Añade `--proxy-server=http://host:port` a `ChromeOptions` (o a `EdgeOptions`) y arranca el driver con esas opciones. Chrome ignora las credenciales escritas en esa dirección, así que tienes dos caminos: autorizar la IP de tu servidor en el proxy, o responder al desafío `407` del proxy mediante el Chrome DevTools Protocol con la pequeña función auxiliar (helper) que verás más abajo. Selenium Wire está archivado y Chrome 137 y posteriores ignoran las extensiones cargadas por línea de comandos, por lo que las recetas antiguas ya no funcionan.

## ¿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](https://www.selenium.dev/documentation/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?](/es/blog/playwright-vs-selenium).

## ¿Cómo funciona un proxy en Selenium?

En Selenium el proxy pertenece a la sesión del navegador, no a una petición concreta:

1. Pones el proxy en las opciones del navegador, como el argumento de Chrome `--proxy-server` o como un objeto `Proxy` (la capacidad `proxy` del estándar WebDriver).
2. El driver arranca el navegador con esa configuración, que se aplica a todas las pestañas hasta `driver.quit()`.
3. Para una página `https://`, el navegador envía `CONNECT host:443` al proxy y abre un túnel cifrado. Para una página `http://`, envía la URL completa al proxy.
4. Si el proxy pide inicio de sesión, responde `407 Proxy Authentication Required`. Este es el paso que el estándar WebDriver no cubre.
5. 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:

```bash
pip install selenium
```

**Paso 2: consigue un servidor proxy.** Elige un producto en la [página de proxies](/es/proxy); 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):

```python
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](https://www.w3.org/TR/webdriver2/#proxy) tiene claves para las direcciones del proxy, pero ninguna para el usuario o la contraseña, y la [documentación de proxies de Chromium](https://chromium.googlesource.com/chromium/src/+/HEAD/net/docs/proxy.md) 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](/es/blog/proxy-authentication-methods).

### Opción 2: responder al 407 con el Chrome DevTools Protocol

Chrome y Edge exponen el [dominio Fetch del DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/tot/Fetch/). 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.

```python
# 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 ws
```

Usarlo cuesta una sola línea después de arrancar el driver:

```python
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](https://github.com/wkeeling/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](/es/blog/how-to-use-proxy-with-seleniumbase).

## ¿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:

```python
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.

```python
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?](/es/blog/socks5-proxy-101) y en [Diferencia entre SOCKS y HTTP](/es/blog/socks-vs-http-proxy); los [Proxies SOCKS5](https://proxynet.io/es/socks5-proxy) 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](https://proxynet.io/es/https-proxy).

## ¿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.

```java
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](https://proxynet.io/es/rotating-proxy), 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](https://proxynet.io/es/sticky-proxy), 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](https://proxynet.io/es/residential-proxy); más detalles en [Qué es la rotación de IP y cómo funciona](/es/blog/ip-rotation-explained) y en [Cómo rotar proxies en Python: guía con código](/es/blog/how-to-rotate-proxies-in-python).

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](https://proxynet.io/es/datacenter-proxy), y si un flujo de varios pasos no debe cambiar nunca de dirección, los [Proxies ISP](https://proxynet.io/es/static-isp-residential-proxy) 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.

```python
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](/es/blog/http-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](/es/blog/webrtc-dns-leak). Tienes una rutina completa en [¿Funciona tu proxy? Cómo probar un proxy](/es/blog/how-to-test-a-proxy) y una comprobación de una línea en la terminal en [cURL con proxy](/es/blog/curl-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](/es/blog/max-retries-exceeded-with-url).

## 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](/es/blog/competitor-price-tracking) y [seguimiento de precios con proxies](/es/price-monitoring).
- **Localización y QA**: cargar tu propio sitio desde varios países antes de un lanzamiento; mira [pruebas de aplicaciones](/es/app-testing).
- **Verificación de anuncios**: comprobar tus anuncios en las regiones por las que pagas; mira [verificación de anuncios](/es/ad-verification).
- **Recogida de datos** de páginas que necesitan JavaScript: [extracción de datos](/es/data-scraping).

Un proxy cambia el origen de la petición, no lo que el sitio permite: lee su [robots.txt](/es/blog/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](/es/blog/playwright-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](/es/proxy) y toma los datos del gateway del Generador de endpoints.
