Configuración de proxy en Python requests, conexión de proxies SOCKS5 y HTTP
Esta guía explica paso a paso cómo conectar el proxy HTTP y SOCKS5 de Socks5Proxy con la biblioteca Python requests, autenticación con username y password, y código para rotar la lista y reintentos.
¿Qué necesito preparar?
Necesitas Python 3.8 o superior y la biblioteca requests. Para usar SOCKS5, también debes instalar el paquete de soporte SOCKS. Instalar requests[socks] también instala PySocks, lo que te permite usar direcciones socks5 y socks5h.
Encuentra la información de tus proxies en 'Mis Proxies' en el dashboard. Ejemplo: IP 198.51.100.23, puerto HTTP 8000, puerto SOCKS5 1080, usuario spx_user, contraseña spx_pass. Sustituye con tus valores reales.
pip install "requests[socks]"¿Cómo me conecto a un proxy HTTP?
requests envía solicitudes a través del proxy si añades la dirección al diccionario proxies. Es importante añadir la misma dirección de proxy HTTP tanto para http como para https. Si falta https, las solicitudes HTTPS no pasarán por el proxy.
Las solicitudes a sitios HTTPS pasan por el proxy mediante el método CONNECT, por lo que el contenido se transmite cifrado de principio a fin. El siguiente código solicita una dirección de verificación de IP e imprime la IP del proxy en la respuesta.
import requests
proxy = "http://spx_user:spx_pass@198.51.100.23:8000"
proxies = {"http": proxy, "https": proxy}
r = requests.get("https://api.ipify.org?format=json", proxies=proxies, timeout=20)
print(r.status_code, r.json()) # the "ip" field should show the proxy IP¿Cómo conectar un proxy SOCKS5?
Recomendamos usar socks5h://. socks5h delega la resolución DNS al proxy, ocultando tus consultas DNS y resolviendo según la ubicación del proxy. socks5:// resuelve DNS localmente antes de enviar la IP al proxy.
Usa puerto SOCKS5. No introduzcas direcciones SOCKS5 en puertos HTTP - verifica ambos puertos por línea.
import requests
proxy = "socks5h://spx_user:spx_pass@198.51.100.23:1080"
proxies = {"http": proxy, "https": proxy}
r = requests.get("https://api.ipify.org?format=json", proxies=proxies, timeout=20)
print(r.json())¿Cómo rotar entre varios proxies para enviar solicitudes?
Al recopilar muchas páginas, el método básico es recibir una lista y usar el siguiente proxy para cada solicitud. El siguiente código recibe una lista SOCKS5 a través de la API y la usa en orden, reintentando solicitudes fallidas con otro proxy hasta 3 veces. También incluye un tiempo de espera para no hacer solicitudes demasiado rápido al mismo dominio.
En lugar de descartar proxies fallidos, es mejor pausarlos y reintentarlos más tarde. Muchos errores son temporales y causados por el sitio destino.
import itertools
import time
import requests
API = "https://socks5proxy.io/api/v1"
KEY = "YOUR_API_KEY"
lines = requests.get(
API + "/proxies/download",
params={"format": "user:pass@ip:port", "protocol": "socks5"},
headers={"Authorization": "Bearer " + KEY},
timeout=30,
).text.split()
pool = itertools.cycle(lines)
def fetch(url, tries=3):
for _ in range(tries):
p = "socks5h://" + next(pool)
try:
r = requests.get(url, proxies={"http": p, "https": p}, timeout=20)
if r.status_code == 200:
return r.text
except requests.RequestException:
pass
time.sleep(1)
return None
for page in range(1, 6):
html = fetch("https://example.com/list?page=" + str(page))
print(page, "ok" if html else "failed")
time.sleep(0.5)¿Cómo mantener sesiones y cookies?
Para flujos con cookies persistentes (como inicio de sesión o paginación), fija un proxy por sesión requests.Session. Asignando la dirección al atributo proxies, todas las solicitudes de esa sesión usarán la misma IP. Cierra la sesión al terminar y crea una nueva con el siguiente proxy.
Define User-Agent y Accept-Language por sesión para una apariencia consistente en los sitios destino.
import requests
s = requests.Session()
s.proxies = {
"http": "http://spx_user:spx_pass@198.51.100.23:8000",
"https": "http://spx_user:spx_pass@198.51.100.23:8000",
}
s.headers.update({"User-Agent": "Mozilla/5.0", "Accept-Language": "en-US,en;q=0.9"})
s.get("https://example.com/", timeout=20) # cookies are stored in the session
r = s.get("https://example.com/account", timeout=20) # same IP, same cookies
print(r.status_code)
s.close()¿Cómo se usa la autorización por IP?
Si registras la IPv4 del servidor donde se ejecuta este código en el panel de control, puedes usar la dirección sin nombre de usuario y contraseña. Esto facilita la implementación del mismo código en varios servidores sin almacenar contraseñas en el código o archivos de configuración. También puedes elegir el formato ip:port al obtener la lista.
import requests
proxy = "http://198.51.100.23:8000" # no user or password, server IP is authorized in the dashboard
r = requests.get("https://api.ipify.org", proxies={"http": proxy, "https": proxy}, timeout=20)
print(r.text)¿Cómo enviar múltiples solicitudes rápidamente?
requests espera hasta que una solicitud termina, por lo que para obtener muchas páginas rápidamente, debes ejecutar múltiples tareas simultáneamente. La forma más fácil es usar ThreadPoolExecutor de concurrent.futures. Mantén el número de tareas menor que el número de proxies para evitar sobrecargar una IP.
El siguiente código divide una lista de direcciones entre 20 workers, y cada worker elige el siguiente proxy de la lista. itertools.cycle no tiene problemas al obtener valores en múltiples hilos, pero si necesitas un orden exacto, usa un bloqueo.
import itertools
from concurrent.futures import ThreadPoolExecutor
import requests
lines = open("proxies.txt").read().split() # user:pass@ip:port per line
pool = itertools.cycle(lines)
def get(url):
p = "http://" + next(pool)
try:
return url, requests.get(url, proxies={"http": p, "https": p}, timeout=20).status_code
except requests.RequestException as e:
return url, type(e).__name__
urls = ["https://example.com/item/" + str(i) for i in range(200)]
with ThreadPoolExecutor(max_workers=20) as ex:
for url, result in ex.map(get, urls):
print(url, result)¿Se pueden usar bibliotecas asíncronas como httpx o aiohttp?
Sí. httpx acepta la dirección proxy al crear el cliente, y con httpx[socks] instalado puedes usar direcciones SOCKS5. El cliente asíncrono AsyncClient también acepta el mismo parámetro.
aiohttp requiere que pases la dirección del proxy HTTP en el parámetro proxy para cada solicitud, y proxy_auth con aiohttp.BasicAuth. aiohttp no admite SOCKS de forma nativa, por lo que si necesitas SOCKS5, debes usar el conector del paquete aiohttp-socks.
El enfoque asíncrono maneja miles de solicitudes con pocos recursos, pero sin límites puede saturar sitios y proxies. Usa asyncio.Semaphore para controlar solicitudes concurrentes.
import httpx
with httpx.Client(proxy="http://spx_user:spx_pass@198.51.100.23:8000", timeout=20) as client:
print(client.get("https://api.ipify.org").text)¿Cómo soluciono errores comunes?
El error 'Missing dependencies for SOCKS support' significa que requests[socks] no está instalado. Vuelve a instalarlo en el mismo entorno virtual.
407 Proxy Authentication Required ocurre cuando el nombre de usuario o contraseña son incorrectos, o cuando usas autorización IP pero la IP del servidor no está registrada. Si tu contraseña tiene caracteres especiales, debes codificarla con urllib.parse.quote.
Los tiempos de espera agotados suelen ocurrir debido a puertos incorrectos. Asegúrate de usar el puerto HTTP para direcciones HTTP y el puerto SOCKS5 para direcciones socks5h. Incluir un valor de timeout evita que solicitudes sin respuesta detengan todo el proceso.
- Error SOCKS: pip install "requests[socks]"
- 407: Verifica nombre de usuario/contraseña o las IPs registradas
- Tiempo de espera agotado: diferencia entre puerto HTTP y SOCKS5
- Agregar timeout a todas las solicitudes