Proxy para Python

Python es el lenguaje n.º 1 para el web scraping y la automatización. Sin embargo, cualquier script tarde o temprano se enfrenta a un bloqueo de IP. Para evitarlo, es necesario integrar proxies de manera adecuada.

En esta guía, analizaremos cómo conectar un proxy en los cuatro escenarios más populares: desde peticiones simples hasta el control del navegador.


📌 Método 1. Biblioteca requests (El más popular)

Si estás escribiendo un scraper básico o trabajando con una API, utilizas requests. Aquí, los proxies se pasan a través de un diccionario (dict) convencional.

Código:

import requests

# Formato: login:password@ip:port
# En CyberYozh App utilizamos el puerto 5959 para HTTP
proxy = "http://user:pass@51.77.190.247:5959"

proxies = {
    "http": proxy,
    "https": proxy
}

try:
    # ¡Es obligatorio indicar el timeout!
    response = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
    print(f"Tu IP: {response.json()['origin']}")
except Exception as e:
    print(f"Error: {e}")

Consejo: No escribas los proxies directamente en el código (hardcoding). Es mejor extraerlos de las variables de entorno (os.getenv).

Si deseas utilizar SOCKS5 en Python, necesitas:

1. Instalar una biblioteca adicional: requests por sí solo no es compatible con SOCKS. Debes instalar un complemento:

pip install requests[socks]
# o bien
pip install pysocks

 

2. Cambiar el esquema en el código: Aquí el puerto y la sintaxis cambian a 9595 y socks5h://.

import requests

# Utilizamos socks5h para evitar fugas de DNS (Remote DNS resolution)
socks_proxy = "socks5h://user:pass@51.77.190.247:9595"

proxies = {
    "http": socks_proxy,
    "https": socks_proxy
}

try:
    response = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
    print(f"Tu IP vía SOCKS5: {response.json()['origin']}")
except Exception as e:
    print(f"Error: {e}")

 


🤖 Método 2. Biblioteca Selenium (Emulación de navegador)

Si el sitio utiliza JavaScript complejo (React, Vue), Single Page Application (SPA) o protección Cloudflare, el requests convencional no servirá, ya que no puede ejecutar código JS. Necesitas Selenium, que abre y controla un navegador real (Chrome/Firefox).

⚠️ El problema principal: Autenticación

El Chrome estándar tiene un inconveniente: no admite el envío de usuario y contraseña del proxy mediante argumentos de inicio. Si intentas pasar http://user:pass@ip:port, el navegador ignorará la autenticación y mostrará una ventana emergente solicitando la contraseña, lo que romperá la automatización.

✅ Solución: Biblioteca selenium-wire

Se trata de una extensión para el Selenium convencional que permite interceptar peticiones y añadir automáticamente el usuario y contraseña del proxy.

Instalación:

pip install selenium-wire

 

Código (Configuración correcta con autenticación):

# Atención: importamos webdriver desde seleniumwire, no desde selenium
from seleniumwire import webdriver 

# Tus datos de proxy de CyberYozh App
PROXY_HOST = "51.77.190.247"
PROXY_PORT = "5959" # Puerto para HTTP
PROXY_USER = "tu_usuario"
PROXY_PASS = "tu_contraseña"

# Formamos el diccionario de configuración
proxy_options = {
    'proxy': {
        'http': f'http://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}',
        'https': f'http://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}',
        'no_proxy': 'localhost,127.0.0.1' # No usar proxy para direcciones locales
    }
}

# Inicializamos el navegador con la opción seleniumwire_options
driver = webdriver.Chrome(seleniumwire_options=proxy_options)

print("Navegador iniciado, comprobando IP...")
driver.get("https://httpbin.org/ip")

# Mostramos el contenido de la página (debería aparecer tu IP de proxy)
print(driver.find_element("tag name", "body").text)

driver.quit()

 

Por qué funciona: selenium-wire crea un servidor intermedio local que se encarga de la comunicación con tu proxy. El navegador cree que trabaja sin contraseña, mientras que la biblioteca se encarga de "pegar" las cabeceras de autorización necesarias. Es el método más fiable para Python.

Selenium y SOCKS5:

Al igual que con requests, para que selenium-wire funcione con proxies SOCKS, debes instalar la biblioteca pysocks (si aún no la tienes):

pip install pysocks

 

Código para SOCKS5 (Selenium Wire)

La lógica es la misma: las claves del diccionario ('http', 'https') le indican a la biblioteca qué tráfico interceptar, y los valores (socks5://...) hacia dónde dirigirlo.

from seleniumwire import webdriver  # ¡Importar específicamente de seleniumwire!

# Tus datos de proxy SOCKS5
PROXY_HOST = "51.77.190.247"
PROXY_PORT = "9595"  # Asegúrate de que sea el puerto para SOCKS5 (suele ser distinto al HTTP)
PROXY_USER = "tu_usuario"
PROXY_PASS = "tu_contraseña"

# Configuración
proxy_options = {
    'proxy': {
        # El esquema cambia a socks5://
        'http': f'socks5://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}',
        'https': f'socks5://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}',
        'no_proxy': 'localhost,127.0.0.1'
    }
}

# Inicio del navegador
# Se pueden añadir opciones comunes de Chrome (headless, etc.) vía chrome_options=...
driver = webdriver.Chrome(seleniumwire_options=proxy_options)

try:
    print("Navegador iniciado, comprobando IP...")
    driver.get("https://httpbin.org/ip")

    # Mostramos la IP
    print(driver.find_element("tag name", "body").text)

    # Recomiendo comprobar el tipo de proxy en un checker más detallado
    # driver.get("https://browserleaks.com/ip")

except Exception as e:
    print(f"Error: {e}")
finally:
    driver.quit()

 

¿Cuál es la diferencia?

En el diccionario proxy_options hemos cambiado el esquema de http:// a socks5://.

Fíjate en las claves del diccionario: NO cambiamos las claves 'http' y 'https' por 'socks'.

  • La clave 'https' significa: "Cuando el navegador solicite sitios HTTPS..."

  • El valor socks5://... significa: "...envíalos a través de este túnel SOCKS5".

¿Y qué pasa con el DNS (socks5h)?

En selenium-wire, la resolución de DNS corre a cargo de la lógica interna de la biblioteca. Normalmente, ella misma gestiona el redireccionamiento de las peticiones DNS a través del proxy si se usa el esquema socks5, ya que selenium-wire actúa como Man-in-the-Middle (intermediario) entre el navegador e internet.

Si notas alguna fuga de DNS (tu proveedor real es visible), intenta indicar socks5h:// en la cadena de conexión; selenium-wire admite este formato gracias a la biblioteca requests que utiliza internamente.


🚀 Método 3. Biblioteca aiohttp (Asincronía)

Cuando necesitas scrapear 10,000 páginas por minuto, se utiliza el enfoque asíncrono (async/await). En este caso, el requests convencional no es apto, se requiere aiohttp.

Código:

import aiohttp
import asyncio

async def fetch_ip():
    proxy_auth = aiohttp.BasicAuth('user', 'pass') # Login y password por separado
    proxy_url = "http://51.77.190.247:5959"

    async with aiohttp.ClientSession() as session:
        async with session.get("https://httpbin.org/ip", 
                               proxy=proxy_url, 
                               proxy_auth=proxy_auth) as resp:
            print(await resp.json())

asyncio.run(fetch_ip())

 

SOCKS5 para aiohttp

Con aiohttp, la situación es un poco más compleja que con requests. La biblioteca aiohttp no admite de serie proxies SOCKS. Solo puede trabajar con proxies HTTP.

Para "enseñarle" a trabajar con SOCKS5, hay que utilizar un conector específico.

1. Instalación

Necesitarás la biblioteca puente aiohttp-socks:

pip install aiohttp-socks

 

2. Código (enfoque correcto mediante Connector)

A diferencia del ejemplo HTTP donde pasábamos el proxy en cada petición (session.get(..., proxy=...)), para SOCKS5 configuramos el proxy una sola vez al crear la sesión.

Esto es incluso mejor para el rendimiento (conexión Keep-Alive).

import aiohttp
import asyncio
from aiohttp_socks import ProxyConnector # Importamos el conector

async def fetch_ip():
    # Formamos la cadena de conexión.
    # Nota: integramos usuario y contraseña directamente en la URL.
    socks_url = "socks5://user:pass@51.77.190.247:9595"

    # Creamos el conector
    # rdns=True es el análogo a socks5h (protección contra fugas de DNS).
    # Es OBLIGATORIO para el anonimato.
    connector = ProxyConnector.from_url(socks_url, rdns=True)

    # Pasamos el conector a ClientSession
    # Ahora toda esta sesión funcionará a través de SOCKS5
    async with aiohttp.ClientSession(connector=connector) as session:
        try:
            # ATENCIÓN: Dentro de .get() ya NO HACE FALTA escribir proxy=...
            # El proxy ya está "integrado" en la sesión mediante el conector.
            async with session.get("https://httpbin.org/ip") as resp:
                print(await resp.json())
        except Exception as e:
            print(f"Error: {e}")

if __name__ == '__main__':
    # Inicio correcto para Windows/Linux
    asyncio.run(fetch_ip())

 

🔍 ¿Cuáles son las principales diferencias con la variante HTTP?
  1. Biblioteca: Hemos añadido from aiohttp_socks import ProxyConnector.

  2. Lugar de configuración:

    • Antes: session.get(..., proxy=...) (configuración en cada petición).

    • Ahora: aiohttp.ClientSession(connector=...) (configuración de toda la sesión).

  3. DNS (rdns=True): El parámetro rdns=True hace lo mismo que socks5h: obliga a resolver los dominios en el lado del proxy, ocultando a tu proveedor los sitios que visitas.

Este código es ideal para procesar 10,000 páginas, ya que el connector gestiona eficientemente el pool de conexiones a través del túnel SOCKS.


🔧 Método 4. Uso de variables de entorno (Mejor práctica)

Los desarrolladores profesionales no escriben proxies dentro del código. Es inseguro (si subes el código a GitHub, te robarán los proxies). Python puede detectar automáticamente los proxies del sistema.

En la terminal (Linux/Mac):

export HTTP_PROXY="http://user:pass@51.77.190.247:5959"

 

En el código:

import requests
# ¡No hace falta pasar ningún argumento de proxies!
# La biblioteca encontrará los ajustes del sistema por sí sola.
requests.get("https://httpbin.org/ip")  

 


💡 ¿Qué proxy elegir para un script de Python?

El código es solo una parte. Lo fundamental es la calidad del proxy y el método de rotación. Según la tarea, la arquitectura de tu script variará.

1. Datacenter (IPv4, IPv6)

Ideal para: Peticiones API sencillas, descarga de archivos, trabajo con sitios sin protecciones estrictas.

  • Lógica en Python: Si una IP es bloqueada, simplemente cámbiala por la siguiente de tu lista mediante el script.

  • Ventaja: Alta velocidad (hasta 1 Gbps) y precio reducido.

2. Residenciales Rotativos

Ideal para: Scraping intensivo (Amazon, buscadores), evasión de Cloudflare y recopilación de grandes volúmenes de datos.

  • Cómo funciona la rotación: No necesitas escribir un código complejo para rotar. En CyberYozh App utilizamos un «Generador inteligente de credenciales». Cambias el comportamiento del proxy simplemente modificando el login:

    • login-res-any: El script obtiene una IP nueva con cada petición (requests.get).

    • login-res-any-sid-12345678: La IP se mantiene vinculada a ese número (sid) por hasta 1 minuto.
    • login-resfix: El script mantiene la IP (Sticky Session) para procesos de autenticación.

  • Ventaja para Python: Utilizas solo una cadena de conexión y accedes a millones de IPs.

👉 Puedes leer más sobre la rotación de proxies residenciales aquí.

3. Proxies Móviles (4G/LTE)

Ideal para: Registro de cuentas, gestión de redes sociales (Instagram, TikTok) y emulación de usuarios reales vía Selenium/Appium. Ofrecen el mayor nivel de confianza (trust).

Existen dos escenarios de gestión en el código:

  • 🅰️ Privados (Private): Rotación vía enlace Alquilas el módem completo. Para cambiar la IP, tu script de Python debe "llamar" a un enlace API específico.

    • Ejemplo de lógica:

      # 1. Ejecutar ciclo de acciones
      do_registration()
      # 2. Reiniciar módem vía API
      requests.get("https://app.cyberyozh.com/api/v1/...") 
      time.sleep(15) # Esperar a que el módem se reconecte
      # 3. Iniciar nuevo ciclo
  • 🅱️ Compartidos (Shared): Autorrotación La IP cambia sola según el temporizador del servicio (ej. cada 5 o 30 minutos).

    • Lógica en Python: Debes gestionar las interrupciones de conexión. Si durante una petición el módem se está reiniciando, el script debe capturar el error ConnectionError, esperar unos segundos y reintentar (Retry).

👉 Puedes leer más sobre proxies móviles aquí.


Conclusión

Integrar un proxy en Python apenas requiere 3-5 líneas de código. Lo vital es escoger el tipo de proxy adecuado para tu objetivo y la biblioteca correspondiente.

👉 ¿Listo para empezar a programar? En el catálogo de CyberYozh App encontrarás todos los tipos de proxies mencionados. Elige el plan que mejor se adapte a tus necesidades (scraping, registros o navegación), copia los accesos e intégralos en tu proyecto en cuestión de minutos.