# ¿Cómo se usa un proxy residencial asiático con Python Requests?

> Para usar un proxy con Python Requests, pasa a cada solicitud un diccionario proxies como {"https": "http://USERNAME-country-jp:PASSWORD@gw.jadeproxies.com:7777"}. Con Jade Proxies, el nombre de usuario también selecciona la ciudad y una sesión fija (sticky), y SOCKS5 funciona igual con socks5h:// en el puerto 7778.

Fuente: https://jadeproxies.com/es/how-to-use-a-proxy-with-python-requests/ · Jade Proxies · Actualizado 29 de octubre de 2026

**Cifra clave: $50** — Nuestra tabla de precios muestra que un millón de páginas descargadas con Python Requests cuestan $50 en tráfico residencial con el plan 100 GB, suponiendo 100 KB transferidos por página. (Tabla de precios de Jade Proxies, 29 de octubre de 2026; el peso de 100 KB por página es una suposición, no una medición)


## ¿Qué necesitas antes de empezar?

Necesitas Python 3, la biblioteca Requests y credenciales de proxy. Jade Proxies admite usuario y contraseña, o lista de IP permitidas (hasta 10 IP); subusuarios con sus propias credenciales y límite de tráfico; claves de API que puedes revocar en cualquier momento. Todos los ejemplos envían el tráfico a través del gateway `gw.jadeproxies.com`: el puerto 7777 para HTTP y HTTPS, y el puerto 7778 para SOCKS5.

1. **Instala Requests con soporte SOCKS.** Ejecuta `pip install "requests[socks]"`, que instala Requests y PySocks.
2. **Guarda tus credenciales.** Pon el usuario y la contraseña del proxy de tu cuenta de Jade Proxies en las variables de entorno `PROXY_USER` y `PROXY_PASS`, no en el código.
3. **Crea el diccionario del proxy HTTP.** Asigna las claves `http` y `https` a `http://USER:PASS@gw.jadeproxies.com:7777`; a los sitios HTTPS se accede mediante un túnel CONNECT, así que el TLS se mantiene de extremo a extremo.
4. **Cambia a SOCKS5 cuando lo necesites.** Usa `socks5h://USER:PASS@gw.jadeproxies.com:7778` para que el DNS se resuelva en la salida, en el país de destino.
5. **Segmenta por país y ciudad.** Amplía el nombre de usuario con `-country-jp` y luego `-city-osaka`, según el formato `USERNAME-country-{cc}-city-{city}-session-{id}-ttl-{minutes}`.
6. **Conserva una IP con una sesión fija (sticky).** Añade `-session-ID-ttl-MINUTES` y reutiliza un `requests.Session`; la IP se conserva hasta 30 minutos (la IP puede cambiar antes).
7. **Verifica la IP de salida.** Solicita `https://ipinfo.io/json` a través del proxy y comprueba el campo `country` antes del trabajo real.
8. **Configura timeouts y reintentos.** Pasa `timeout=(10, 30)` y monta un `HTTPAdapter` con una política `Retry` para las respuestas 429 y 5xx.
9. **Ejecuta solicitudes en paralelo.** Usa un `ThreadPoolExecutor`; una solicitud por conexión da una IP nueva por solicitud.

## ¿Cómo se configura un proxy HTTP en Python Requests?

Se configura un proxy HTTP pasando un diccionario `proxies` cuyas claves `http` y `https` apuntan ambas al puerto HTTP del gateway.

```python
import os
import requests
from urllib.parse import quote

USER = os.environ["PROXY_USER"]
PASS = quote(os.environ["PROXY_PASS"], safe="")  # encodes @ : / in passwords

proxy = f"http://{USER}-country-jp:{PASS}@gw.jadeproxies.com:7777"
proxies = {"http": proxy, "https": proxy}

r = requests.get("https://example.com/", proxies=proxies, timeout=(10, 30))
print(r.status_code)
```

La URL del proxy empieza por `http://` incluso en la clave `https`: Requests abre un túnel CONNECT a través del gateway y la sesión TLS se establece entre tu script y el sitio. Un estado `407` significa que el gateway rechazó el usuario o la contraseña.

## ¿Cómo se usa un proxy SOCKS5 con Requests?

Para usar SOCKS5, cambia el esquema a `socks5h` y el puerto a 7778; el resto del código no cambia.

```python
proxy = f"socks5h://{USER}-country-kr:{PASS}@gw.jadeproxies.com:7778"
proxies = {"http": proxy, "https": proxy}
r = requests.get("https://example.com/", proxies=proxies, timeout=(10, 30))
```

Con `socks5h`, el gateway resuelve el nombre de host en Corea. Con `socks5` a secas, lo resuelve tu propia máquina, lo que expone la consulta a tu DNS local y puede devolver un servidor fuera del país de destino.

## ¿Cómo se eligen el país y la ciudad?

Eliges la salida añadiendo parámetros al nombre de usuario. Jade Proxies ofrece segmentación por país y ciudad en todos los planes; segmentación por ASN sin coste adicional; la disponibilidad de ciudades varía.

| Objetivo | Nombre de usuario |
|---|---|
| Cualquier IP en Japón | `USER-country-jp` |
| Osaka | `USER-country-jp-city-osaka` |
| Bombay | `USER-country-in-city-mumbai` |
| Bangkok, la misma IP durante 10 minutos | `USER-country-th-city-bangkok-session-a1b2c3-ttl-10` |

Los códigos de país son los códigos ISO de dos letras de los 13 países que aparecen en la página de [proxies residenciales asiáticos](https://jadeproxies.com/es/asian-residential-proxies/). Una pequeña función auxiliar mantiene el formato en un solo lugar:

```python
def proxy_url(country, city=None, session=None, ttl=10, socks=False):
    user = f"{USER}-country-{country}"
    if city:
        user += f"-city-{city}"
    if session:
        user += f"-session-{session}-ttl-{ttl}"
    if socks:
        return f"socks5h://{user}:{PASS}@gw.jadeproxies.com:7778"
    return f"http://{user}:{PASS}@gw.jadeproxies.com:7777"
```

## ¿Cómo se mantiene la misma IP entre solicitudes?

Mantienes la misma IP añadiendo un ID de sesión y un TTL al nombre de usuario y enviando las solicitudes a través de un único `requests.Session`.

```python
import uuid

p = proxy_url("jp", "tokyo", session=uuid.uuid4().hex[:8], ttl=30)
s = requests.Session()
s.proxies = {"http": p, "https": p}
for page in range(1, 4):
    s.get(f"https://example.jp/list?page={page}", timeout=(10, 30))
```

Sin ID de sesión, cada nueva conexión obtiene una IP del pool de IP, normalmente distinta; para obtener una IP nueva en cada solicitud, envía una solicitud por conexión (desactiva keep-alive). Un `requests.Session` mantiene las conexiones abiertas, así que usa llamadas simples a `requests.get()` cuando quieras una IP nueva en cada solicitud. La [guía de proxies rotativos frente a sesiones fijas](https://jadeproxies.com/es/rotating-vs-sticky-proxies/) explica qué modo conviene a cada tarea.

## ¿Cómo se comprueba que la IP de salida está en el país correcto?

Compruebas la salida consultando un endpoint de información de IP a través del proxy y comparando su código de país con el que solicitaste.

```python
info = requests.get("https://ipinfo.io/json", proxies=proxies, timeout=15).json()
assert info["country"] == "JP", info
print(info["ip"], info.get("city"), info.get("org"))
```

El campo `org` indica la red propietaria de la IP; en una salida residencial es un proveedor de internet (ISP) doméstico, no una empresa de hosting. Ejecuta esta comprobación una vez por país antes de un trabajo largo.

## ¿Cómo se gestionan los timeouts y los reintentos?

Configura un timeout de conexión y otro de lectura en cada llamada y reintenta los errores transitorios con backoff, porque una salida residencial es una conexión doméstica que puede caerse en cualquier momento.

```python
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

retry = Retry(total=3, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504], allowed_methods=["GET"])
s = requests.Session()
s.mount("http://", HTTPAdapter(max_retries=retry))
s.mount("https://", HTTPAdapter(max_retries=retry))
r = s.get("https://example.com/", proxies=proxies, timeout=(10, 30))
```

Los reintentos consumen tráfico solo cuando llegan al sitio: el consumo incluye todos los datos enviados y recibidos a través del proxy (subida y bajada, cabeceras incluidas); 1 GB = 1.000.000.000 bytes; los intentos de conexión que fallan antes de llegar al destino no se contabilizan.

## ¿Cómo se envían solicitudes en paralelo?

Envías solicitudes en paralelo con un pool de hilos, porque Requests es síncrono y cada hilo espera en su propia conexión.

```python
from concurrent.futures import ThreadPoolExecutor

def fetch(url):
    r = requests.get(url, proxies=proxies, timeout=(10, 30))
    return url, r.status_code, len(r.content)

with ThreadPoolExecutor(max_workers=10) as pool:
    for url, status, size in pool.map(fetch, urls):
        print(status, size, url)
```

Cada llamada a `requests.get()` abre su propia conexión, así que cada solicitud obtiene su propia IP. Empieza con 10 workers, aumenta el número mientras la proporción de errores y respuestas 429 se mantenga estable, y respeta los límites de frecuencia y las condiciones de cada sitio.

## ¿Cuánto tráfico consume un rastreo con Python Requests?

Un rastreo consume aproximadamente el número de páginas multiplicado por la transferencia media por página. La tabla supone 100 KB por página: HTML comprimido más las cabeceras de solicitud y respuesta, sin imágenes. Ese peso es una suposición para el cálculo, no una medición.

| Rastreo | Tráfico | Plan | Coste |
|---|---|---|---|
| 10.000 páginas | 1 GB | Prueba | $1.50 |
| 100.000 páginas | 10 GB | Crecimiento | $6.60 |
| 500.000 páginas | 50 GB | Pro | $26 |
| 1.000.000 páginas | 100 GB | Empresa | $50 |

Nuestra tabla de precios muestra que un millón de páginas cuestan $50 en tráfico residencial con el plan 100 GB con ese peso. El peso de las páginas varía según el sitio, así que mide primero tu propia media con una muestra de 1.000 páginas; la [guía de Shopee y Lazada](https://jadeproxies.com/es/best-proxy-for-shopee-lazada-scraping/) trata los marketplaces. Todos los planes están en la [página de precios](https://jadeproxies.com/es/pricing/), y el tráfico nunca caduca.

## Preguntas frecuentes

### ¿Por qué Requests ignora mi proxy?

Requests aplica un proxy solo a los esquemas de URL presentes en el diccionario `proxies`, así que un diccionario con solo la clave `http` envía las solicitudes HTTPS directamente. Define ambas claves y comprueba que ninguna variable de entorno `NO_PROXY` coincida con el host de destino.

### ¿Qué diferencia hay entre socks5 y socks5h en Requests?

Con `socks5h`, el proxy resuelve el nombre de host en la salida; con `socks5`, tu máquina lo resuelve localmente. Usa `socks5h` para destinos asiáticos, de modo que las respuestas DNS coincidan con el país de salida.

### ¿Cómo obtengo una IP nueva en cada solicitud?

No incluyas el ID de sesión en el nombre de usuario y envía una solicitud por conexión, por ejemplo con llamadas simples a `requests.get()` en lugar de un `Session` compartido. Cada nueva conexión obtiene una IP del pool de IP, normalmente distinta.

### ¿Qué significa un error 407?

Un estado `407 Proxy Authentication Required` significa que el gateway no aceptó las credenciales. Revisa la codificación de la contraseña con `urllib.parse.quote` y la sintaxis del nombre de usuario, por ejemplo `USER-country-jp-city-osaka`.

### ¿Cuánto cuesta una primera prueba?

El plan 1 GB cuesta $1.50, unas 10.000 páginas con la suposición de 100 KB indicada arriba. Se paga desde un saldo en criptomonedas con una recarga de saldo mínima de $1, y el tráfico no utilizado nunca caduca.
