# Proxy en Python Requests: diccionario proxies, auth, SOCKS5

Source: https://ipvolt.com/es/guides/python-requests-proxy
Markdown: https://ipvolt.com/es/guides/python-requests-proxy.md
Language: es

[Inicio de ipvolt](https://ipvolt.com/es.md) / [Guías](https://ipvolt.com/es/guides.md) / Proxy en Python Requests: diccionario proxies, auth, SOCKS5

Integración
Revisado: 2026-09-17
7 min de lectura
Por ipvolt

Configura un proxy en Python Requests: el diccionario proxies, ajustes de Session, credenciales, SOCKS5 con requests[socks], variables de entorno y ProxyError.

## El punto de partida

El diccionario proxies, los valores por defecto a nivel de Session, la codificación de credenciales, SOCKS5, el comportamiento del entorno y las excepciones que lanza Requests cuando falla el paso del proxy.

## Configura un proxy en una petición con el diccionario proxies

Requests selecciona un proxy a partir de un diccionario cuyas claves son esquemas de destino. El valor de https se usa para destinos https://, y el valor de http se usa para destinos http://; ambos suelen apuntar al mismo gateway. La clave all se aplica a cualquier esquema, y una clave como https://example.com fija un host a un gateway concreto.

El valor es la URL del proxy, con su propio esquema. http://host:port es un proxy HTTP ordinario; para un destino https://, Requests le pide que abra un túnel CONNECT. Usa https://host:port como URL del proxy solo cuando el proveedor termina el TLS en el proxy. Pasa siempre un timeout; sin él, un proxy bloqueado detiene la llamada indefinidamente.

### requests.get con proxies · una petición

```python
import requests

PROXIES = {
    "http": "http://proxy.example.invalid:8080",
    "https": "http://proxy.example.invalid:8080",
}

response = requests.get(
    "https://example.com/",
    proxies=PROXIES,
    timeout=(10, 20),
)
print(response.status_code)
```

## Usa una Session para que todas las peticiones compartan el proxy

Una Session mantiene juntos el pool de conexiones, las cookies y la configuración del proxy. Establece session.proxies una vez y cada petición hecha a través de esa Session usará el gateway, mientras que un argumento proxies en una llamada individual sigue teniendo prioridad. Aquí también decides si el entorno del proceso puede aportar configuración: trust_env=False impide que Requests lea HTTP_PROXY, HTTPS_PROXY, NO_PROXY, las credenciales de netrc y la variable REQUESTS_CA_BUNDLE, de modo que solo el código define la ruta.

### requests.Session · configuración de proxy compartida

```python
import requests

with requests.Session() as session:
    session.trust_env = False
    session.proxies.update({
        "http": "http://proxy.example.invalid:8080",
        "https": "http://proxy.example.invalid:8080",
    })
    for url in ("https://example.com/", "https://example.com/robots.txt"):
        response = session.get(url, timeout=(10, 20))
        print(url, response.status_code)
```

## Autenticación del proxy: codifica las credenciales en la URL

Requests envía las credenciales del proxy desde la propia URL del proxy, como http://username:password@host:port; añade la cabecera Proxy-Authorization por ti. El argumento auth es autenticación del destino y no llega al proxy.

Codifica el nombre de usuario y la contraseña por separado para que caracteres como @, : o / no puedan alterar la estructura de la URL, y mantén la PROXY_URL original libre de credenciales. Guarda el script de abajo como proxy_check.py y ejecuta python proxy_check.py después de instalar Requests en un entorno virtual con python -m pip install requests. https://proxy.example.invalid:8443 es solo una ilustración que no funciona.

### proxy_check.py · Python 3 + Requests

```python
import os
from urllib.parse import quote, urlsplit, urlunsplit
import requests

gateway = urlsplit(os.environ["PROXY_URL"])
if gateway.scheme not in {"http", "https"} or not gateway.hostname:
    raise ValueError("Use your provider's HTTP(S) proxy URL")
if gateway.username is not None or gateway.path not in {"", "/"} or gateway.query or gateway.fragment:
    raise ValueError("Keep credentials and paths out of PROXY_URL")
username = quote(os.environ["PROXY_USERNAME"], safe="")
password = quote(os.environ["PROXY_PASSWORD"], safe="")
proxy = urlunsplit((gateway.scheme, f"{username}:{password}@{gateway.netloc}", "", "", ""))

with requests.Session() as session:
    session.trust_env = False
    with session.get(
        "https://example.com/",
        proxies={"http": proxy, "https": proxy},
        timeout=(10, 20),
        allow_redirects=False,
        stream=True,
    ) as response:
        response.raise_for_status()
        print({"status": response.status_code})
```

## Variables de entorno y trust_env

Cuando trust_env se deja en su valor por defecto True, Requests rellena desde el entorno cualquier esquema que no hayas establecido, a través de urllib.request.getproxies(). Acepta HTTP_PROXY, HTTPS_PROXY, ALL_PROXY y NO_PROXY en mayúsculas o minúsculas, y en macOS también lee la configuración de proxy del sistema. Eso es cómodo en una estación de trabajo y una fuente habitual de sorpresas en contenedores, donde una HTTPS_PROXY heredada de la imagen enruta tráfico que creías directo.

NO_PROXY es una lista separada por comas de nombres de host, sufijos de dominio o direcciones IP que evitan el proxy. Para un trabajo cuya ruta deba ser reproducible, establece trust_env=False y pasa los proxies de forma explícita; para un script de estación de trabajo, basta con establecer las variables y llamar a Requests sin argumento proxies.

### HTTPS_PROXY · se detecta cuando trust_env es True

```sh
export HTTPS_PROXY='http://proxy.example.invalid:8080'
export NO_PROXY='localhost,127.0.0.1,.internal.example'
python -c 'import requests; print(requests.get("https://example.com/", timeout=(10, 20)).status_code)'
```

## Proxies SOCKS5: requests[socks], socks5 frente a socks5h

El soporte de SOCKS viene del extra PySocks: instálalo con python -m pip install "requests[socks]" y luego usa una URL de proxy socks5:// o socks5h:// en el mismo diccionario. socks5 resuelve el nombre de host del destino localmente y envía al proxy una dirección IP; socks5h envía el nombre de host para que lo resuelva el proxy, que suele ser lo que espera un gateway remoto. El nombre de usuario y la contraseña van en la URL exactamente igual que con los proxies HTTP.

### proxy socks5h · requests[socks]

```python
import requests

PROXIES = {
    "http": "socks5h://proxy.example.invalid:1080",
    "https": "socks5h://proxy.example.invalid:1080",
}
response = requests.get("https://example.com/", proxies=PROXIES, timeout=(10, 20))
print(response.status_code)
```

## Rota entre varios proxies

Cuando un trabajo necesita repartir las peticiones entre varios gateways, mantén una sola Session para el pool de conexiones y elige el argumento proxies en cada petición. El ejemplo recorre una lista de forma cíclica; un trabajo real la tomaría de la configuración, registraría qué gateway sirvió cada petición y retiraría un gateway tras fallos repetidos en lugar de reintentarlo de inmediato. Que peticiones consecutivas deban conservar la misma dirección de salida es una decisión del modelo de sesión, y muchos proveedores la expresan mediante el nombre de usuario o un puerto dedicado. Sigue la documentación del proveedor en lugar de deducirlo a partir de una petición exitosa.

### itertools.cycle · una Session, varios gateways

```python
from itertools import cycle
import requests

GATEWAYS = cycle([
    "http://proxy-a.example.invalid:8080",
    "http://proxy-b.example.invalid:8080",
])

with requests.Session() as session:
    session.trust_env = False
    for url in ("https://example.com/", "https://example.com/robots.txt"):
        gateway = next(GATEWAYS)
        response = session.get(url, proxies={"http": gateway, "https": gateway}, timeout=(10, 20))
        print(gateway, url, response.status_code)
```

## Entiende qué mide el timeout

La tupla proporciona tiempos de espera separados de conexión y de lectura. Un timeout de lectura limita la espera de datos del socket; no es un plazo total de descarga. Aplica un presupuesto de tiempo de reloj independiente en tu ejecutor de trabajos cuando una tarea completa deba terminar en un plazo fijo. El diagnóstico de arriba transmite y cierra la respuesta sin descargar el cuerpo completo.

Establecer trust_env en False también desactiva la configuración del paquete de CA que Requests deriva del entorno. Si tu organización usa un paquete de confianza personalizado, pasa su archivo aprobado de forma explícita con verify. No uses verify=False para hacer que pase una prueba que falla.

## Lee los errores: ProxyError, 407 y timeouts

Cómo aparece un fallo del proxy depende del esquema del destino. Para un destino https://, el fallo ocurre durante el túnel CONNECT, y Requests lanza requests.exceptions.ProxyError, cuyo mensaje incluye la respuesta del proxy, por ejemplo Tunnel connection failed: 407 Proxy Authentication Required. Para un destino http:// plano no hay túnel, así que un 407 llega como una Response ordinaria con status_code 407 y sin ninguna excepción; compruébalo de forma explícita.

Ejecuta el mismo gateway y destino en curl antes de añadir lógica de reintentos. Registra la clase de la excepción, el número de intento y el tiempo transcurrido, con las credenciales eliminadas. Un error de autenticación reproducible necesita un cambio de configuración; repetirlo con mayor concurrencia solo añade ruido.

- ProxyError con 407: el proxy rechazó las credenciales de la URL. Vuelve a revisar la codificación y el formato de nombre de usuario del proveedor.
- ProxyError con Cannot connect to proxy o un mensaje de resolución de nombres: el host o el puerto del gateway son incorrectos, o esta red no puede alcanzarlo.
- ConnectTimeout: la parte de conexión de la tupla de timeout expiró antes de que el proxy o el destino respondieran. ReadTimeout: la conexión funcionó pero no llegaron datos dentro del límite de lectura.
- SSLError después de un túnel exitoso: la verificación del certificado falló para el destino, o el proxy está interceptando el TLS. Mantén la verificación activada y confírmalo con el proveedor.
- Una petición HTTP exitosa por sí sola no verifica la ubicación de la salida.

## Antes de pasar a producción

- Usa un entorno virtual del proyecto.
- Codifica las credenciales por separado del gateway.
- Decide de forma explícita si el entorno puede aportar configuración de proxy.
- Mantén un plazo del trabajo además de los timeouts de red.

## Fuentes y lecturas adicionales

- [Requests: proxies, environment configuration and SOCKS](https://requests.readthedocs.io/en/latest/user/advanced/#proxies)
- [Requests: timeouts and errors](https://requests.readthedocs.io/en/latest/user/quickstart/#timeouts)
- [Requests API: Session.trust_env and Session.proxies](https://requests.readthedocs.io/en/latest/api/#requests.Session.trust_env)
- [urllib3: proxies and tunneling](https://urllib3.readthedocs.io/en/stable/advanced-usage.html#proxies)
- [Python: urllib.request.getproxies and environment variables](https://docs.python.org/3/library/urllib.request.html#urllib.request.getproxies)
- [Python: URL parsing and quoting](https://docs.python.org/3/library/urllib.parse.html)

## Guías relacionadas

- [Usar un proxy con curl: -x, variables de entorno, SOCKS5 y auth](https://ipvolt.com/es/guides/curl-proxy-setup.md)
- [Variables de entorno de proxy: HTTP_PROXY y NO_PROXY](https://ipvolt.com/es/guides/proxy-environment-variables.md)
- [Diagnostica los timeouts de proxy etapa por etapa](https://ipvolt.com/es/guides/proxy-timeout-troubleshooting.md)

## Sobre ipvolt

Los ejemplos usan configuraciones de proxy genéricas, con enlaces a la documentación técnica original. El comportamiento específico de cada producto debe comprobarse con tu proveedor. ipvolt sigue en desarrollo.

[Leer el original en inglés](https://ipvolt.com/guides/python-requests-proxy.md)

## Entérate cuando se abra el acceso.

ipvolt · En desarrollo

Estamos construyendo infraestructura de proxies para desarrolladores y equipos de datos. Únete a la lista de interés para recibir un aviso cuando ipvolt esté listo.

Un correo cuando se abra el acceso. Nada más.

[Solicitar acceso anticipado](https://ipvolt.com/es/guides/python-requests-proxy#waitlist-closing)

[Privacidad](https://ipvolt.com/privacy)

