Usar proxies en Python (Requests + SDK de ProxyHat)

Aprende a usar proxies en Python con la biblioteca Requests y el SDK de ProxyHat. Cubre autenticación, rotación, segmentación geográfica, manejo de errores y scraping asíncrono.

Usar proxies en Python (Requests + SDK de ProxyHat)

¿Por qué usar proxies en Python?

Python domina el panorama de la extracción de datos. Bibliotecas como Requests, httpx y Scrapy hacen que las llamadas HTTP sean triviales, pero sin proxies, tus scripts reciben bloqueos de IP en minutos. Usar proxies en Python te permite rotar direcciones IP, evadir restricciones geográficas y escalar tus operaciones de scraping de forma fiable.

En esta guía, aprenderás cómo integrar proxies en Python usando el ProxyHat Python SDK y la biblioteca estándar requests. Cada sección incluye código listo para copiar y pegar que puedes ejecutar inmediatamente.

Ya sea que estés construyendo un pipeline de web scraping, monitoreando resultados de SERP, o recopilando datos de precios, esta guía cubre autenticación, rotación de proxies, segmentación geográfica, manejo de errores y escalado en producción.

Instalación y configuración

Instalación del SDK de ProxyHat y Requests

Instala el SDK de ProxyHat para Python y la biblioteca requests usando pip:

pip install proxyhat requests

Para flujos de trabajo asíncronos, instala también httpx y aiohttp:

pip install httpx aiohttp

Obtener tus credenciales de API

Regístrate en ProxyHat y obtén tu clave API desde el panel de control. Necesitarás tu nombre de usuario y contraseña (o clave API) para la autenticación del proxy. Los detalles completos de autenticación están disponibles en la documentación de la API de ProxyHat.

Autenticación y configuración básica

Usando el SDK de ProxyHat

El SDK gestiona la autenticación, rotación y administración de conexiones por ti:

from proxyhat import ProxyHat
client = ProxyHat(
    api_key="your_api_key_here"
)
# Test the connection
info = client.get_account_info()
print(f"Traffic remaining: {info['traffic_remaining']} GB")

Usando credenciales proxy directas con Requests

Si prefieres usar requests directamente, configura la URL del proxy:

import requests
proxy_url = "http://username:password@gate.proxyhat.com:8080"
proxies = {
    "http": proxy_url,
    "https": proxy_url,
}
response = requests.get(
    "https://httpbin.org/ip",
    proxies=proxies,
    timeout=30
)
print(response.json())
# {"origin": "185.xxx.xxx.xxx"}

Solicitud GET simple con un proxy

Aquí tienes un ejemplo completo que envía una solicitud GET a través de un proxy residencial de ProxyHat:

from proxyhat import ProxyHat
client = ProxyHat(api_key="your_api_key_here")
# Make a proxied GET request
response = client.get("https://httpbin.org/ip")
print(f"Status: {response.status_code}")
print(f"IP: {response.json()['origin']}")
print(f"Headers: {response.headers}")

O con la biblioteca estándar requests:

import requests
proxies = {
    "http": "http://user:pass@gate.proxyhat.com:8080",
    "https": "http://user:pass@gate.proxyhat.com:8080",
}
response = requests.get(
    "https://example.com/api/data",
    proxies=proxies,
    timeout=30,
    headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
)
print(response.status_code)
print(response.text[:500])

Elegir el tipo de proxy adecuado

ProxyHat ofrece tres tipos de proxy. Elige según tu caso de uso. Para una comparación más detallada, lee nuestra guía sobre proxies residenciales vs datacenter vs móviles.

Tipo Ideal para Velocidad Riesgo de detección Coste
Residencial Web scraping, seguimiento SERP Media Muy bajo Por GB
Datacenter Tareas de alto volumen y velocidad crítica Rápida Mayor Por IP/mes
Móvil Redes sociales, pruebas de apps Media Más bajo Por GB

Cambiar tipos de proxy en código

from proxyhat import ProxyHat
client = ProxyHat(api_key="your_api_key_here")
# Residential proxy (default)
response = client.get(
    "https://example.com",
    proxy_type="residential"
)
# Datacenter proxy
response = client.get(
    "https://example.com",
    proxy_type="datacenter"
)
# Mobile proxy
response = client.get(
    "https://example.com",
    proxy_type="mobile"
)

Sesiones rotativas vs sticky

Los proxies rotativos asignan una nueva IP por cada solicitud, ideal para scraping a gran escala donde necesitas máximo anonimato. Las sesiones sticky mantienen la misma IP por un período determinado, esencial para flujos de trabajo de múltiples pasos como secuencias de login o navegación paginada.

Proxies rotativos (nueva IP por solicitud)

from proxyhat import ProxyHat
client = ProxyHat(api_key="your_api_key_here")
urls = [
    "https://httpbin.org/ip",
    "https://httpbin.org/ip",
    "https://httpbin.org/ip",
]
for url in urls:
    response = client.get(url, session_type="rotating")
    print(f"IP: {response.json()['origin']}")
# Each request uses a different IP:
# IP: 185.xxx.xxx.1
# IP: 92.xxx.xxx.47
# IP: 78.xxx.xxx.203

Sesiones sticky (misma IP por duración)

from proxyhat import ProxyHat
client = ProxyHat(api_key="your_api_key_here")
# Create a sticky session (maintains IP for up to 30 minutes)
session = client.create_session(duration_minutes=30)
# All requests in this session use the same IP
for page in range(1, 6):
    response = session.get(f"https://example.com/products?page={page}")
    print(f"Page {page}: IP {response.headers.get('X-Proxy-IP')}")
# Same IP across all pages:
# Page 1: IP 185.xxx.xxx.42
# Page 2: IP 185.xxx.xxx.42
# Page 3: IP 185.xxx.xxx.42

Solicitudes con segmentación geográfica

¿Necesitas datos de un país específico? ProxyHat soporta segmentación geográfica en más de 195 ubicaciones. Esto es crítico para scraping localizado de SERP, monitoreo de precios y verificación de contenido.

from proxyhat import ProxyHat
client = ProxyHat(api_key="your_api_key_here")
# Target a specific country
response = client.get(
    "https://www.google.com/search?q=best+restaurants",
    country="US"
)
# Target a specific city
response = client.get(
    "https://www.google.com/search?q=best+restaurants",
    country="US",
    city="New York"
)
# Using raw proxy URL with geo-targeting
# Format: username-country-US:password@gate.proxyhat.com:8080
import requests
proxies = {
    "http": "http://user-country-DE:pass@gate.proxyhat.com:8080",
    "https": "http://user-country-DE:pass@gate.proxyhat.com:8080",
}
response = requests.get("https://www.google.de", proxies=proxies, timeout=30)
print(f"Accessed from Germany: {response.status_code}")

Manejo de errores y reintentos

Las solicitudes de red fallan. Los proxies hacen timeout. Los objetivos te bloquean. Un manejo robusto de errores separa los scrapers de producción de los scripts de prueba.

Lógica básica de reintentos

import time
import requests
from requests.exceptions import ProxyError, Timeout, ConnectionError
def fetch_with_retry(url, proxies, max_retries=3, timeout=30):
    """Fetch a URL with automatic retry on failure."""
    for attempt in range(max_retries):
        try:
            response = requests.get(
                url,
                proxies=proxies,
                timeout=timeout,
                headers={"User-Agent": "Mozilla/5.0"}
            )
            response.raise_for_status()
            return response
        except (ProxyError, Timeout, ConnectionError) as e:
            wait = 2 ** attempt  # Exponential backoff
            print(f"Attempt {attempt + 1} failed: {e}. Retrying in {wait}s...")
            time.sleep(wait)
        except requests.exceptions.HTTPError as e:
            if e.response.status_code == 429:
                wait = 10 * (attempt + 1)
                print(f"Rate limited. Waiting {wait}s...")
                time.sleep(wait)
            elif e.response.status_code >= 500:
                time.sleep(2 ** attempt)
            else:
                raise
    raise Exception(f"Failed to fetch {url} after {max_retries} attempts")
# Usage
proxies = {
    "http": "http://user:pass@gate.proxyhat.com:8080",
    "https": "http://user:pass@gate.proxyhat.com:8080",
}
response = fetch_with_retry("https://example.com/data", proxies)

Usando los reintentos integrados del SDK

from proxyhat import ProxyHat
client = ProxyHat(
    api_key="your_api_key_here",
    max_retries=3,
    timeout=30,
    retry_on_status=[429, 500, 502, 503]
)
# The SDK handles retries automatically
response = client.get("https://example.com/data")
print(response.status_code)

Scraping concurrente con hilos

Las solicitudes secuenciales son lentas. Para cargas de trabajo en producción, usa concurrent.futures de Python para paralelizar solicitudes a través de proxies.

from concurrent.futures import ThreadPoolExecutor, as_completed
from proxyhat import ProxyHat
client = ProxyHat(api_key="your_api_key_here")
urls = [
    "https://example.com/product/1",
    "https://example.com/product/2",
    "https://example.com/product/3",
    "https://example.com/product/4",
    "https://example.com/product/5",
]
def scrape(url):
    """Scrape a single URL through the proxy."""
    response = client.get(url, proxy_type="residential")
    return {"url": url, "status": response.status_code, "length": len(response.text)}
# Run 5 concurrent requests
results = []
with ThreadPoolExecutor(max_workers=5) as executor:
    futures = {executor.submit(scrape, url): url for url in urls}
    for future in as_completed(futures):
        try:
            result = future.result()
            results.append(result)
            print(f"OK: {result['url']} ({result['length']} bytes)")
        except Exception as e:
            print(f"Error: {futures[future]} - {e}")
print(f"\nCompleted: {len(results)}/{len(urls)}")

Scraping asíncrono con asyncio y httpx

import asyncio
import httpx
async def scrape_urls(urls, proxy_url, max_concurrent=10):
    """Scrape multiple URLs concurrently using async proxies."""
    semaphore = asyncio.Semaphore(max_concurrent)
    async def fetch(client, url):
        async with semaphore:
            response = await client.get(url, timeout=30)
            return {"url": url, "status": response.status_code}
    async with httpx.AsyncClient(proxy=proxy_url) as client:
        tasks = [fetch(client, url) for url in urls]
        return await asyncio.gather(*tasks, return_exceptions=True)
# Usage
proxy_url = "http://user:pass@gate.proxyhat.com:8080"
urls = [f"https://example.com/page/{i}" for i in range(1, 51)]
results = asyncio.run(scrape_urls(urls, proxy_url))
successful = [r for r in results if not isinstance(r, Exception)]
print(f"Scraped {len(successful)}/{len(urls)} pages")

Integración con bibliotecas populares de Python

Uso con Requests (Session)

import requests
session = requests.Session()
session.proxies = {
    "http": "http://user:pass@gate.proxyhat.com:8080",
    "https": "http://user:pass@gate.proxyhat.com:8080",
}
session.headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
})
# All requests in this session use the proxy
response = session.get("https://example.com/api/products")
print(response.json())

Uso con httpx

import httpx
proxy_url = "http://user:pass@gate.proxyhat.com:8080"
# Synchronous
with httpx.Client(proxy=proxy_url) as client:
    response = client.get("https://httpbin.org/ip")
    print(response.json())
# Asynchronous
async with httpx.AsyncClient(proxy=proxy_url) as client:
    response = await client.get("https://httpbin.org/ip")
    print(response.json())

Uso con aiohttp

import aiohttp
import asyncio
async def fetch_with_aiohttp():
    proxy_url = "http://user:pass@gate.proxyhat.com:8080"
    async with aiohttp.ClientSession() as session:
        async with session.get(
            "https://httpbin.org/ip",
            proxy=proxy_url,
            timeout=aiohttp.ClientTimeout(total=30)
        ) as response:
            data = await response.json()
            print(f"IP: {data['origin']}")
asyncio.run(fetch_with_aiohttp())

Uso con Scrapy

Añade ProxyHat a tu spider de Scrapy configurando el settings.py:

# settings.py
DOWNLOADER_MIDDLEWARES = {
    "scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware": 110,
}
HTTP_PROXY = "http://user:pass@gate.proxyhat.com:8080"
# Or set per-request in your spider:
import scrapy
class ProductSpider(scrapy.Spider):
    name = "products"
    start_urls = ["https://example.com/products"]
    def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request(
                url,
                meta={"proxy": "http://user:pass@gate.proxyhat.com:8080"},
                callback=self.parse
            )
    def parse(self, response):
        for product in response.css(".product-card"):
            yield {
                "name": product.css("h2::text").get(),
                "price": product.css(".price::text").get(),
            }

Consejos para producción

Pool de conexiones y timeouts

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
session = requests.Session()
# Configure retry strategy
retry_strategy = Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[429, 500, 502, 503, 504],
)
adapter = HTTPAdapter(
    max_retries=retry_strategy,
    pool_connections=10,
    pool_maxsize=20
)
session.mount("http://", adapter)
session.mount("https://", adapter)
session.proxies = {
    "http": "http://user:pass@gate.proxyhat.com:8080",
    "https": "http://user:pass@gate.proxyhat.com:8080",
}
# Robust, production-ready request
response = session.get("https://example.com/data", timeout=(5, 30))
print(response.status_code)

Registro y monitoreo

import logging
import time
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(message)s")
logger = logging.getLogger("scraper")
def monitored_request(session, url):
    """Log request timing and status for monitoring."""
    start = time.time()
    try:
        response = session.get(url, timeout=30)
        elapsed = time.time() - start
        logger.info(f"OK {response.status_code} {url} ({elapsed:.2f}s)")
        return response
    except Exception as e:
        elapsed = time.time() - start
        logger.error(f"FAIL {url} ({elapsed:.2f}s): {e}")
        raise

Variables de entorno para credenciales

Nunca escribas credenciales directamente en el código. Usa variables de entorno:

import os
from proxyhat import ProxyHat
client = ProxyHat(
    api_key=os.environ["PROXYHAT_API_KEY"]
)
# Or with raw proxy URL
proxy_url = os.environ.get(
    "PROXY_URL",
    "http://user:pass@gate.proxyhat.com:8080"
)

Para una lista completa de planes de proxy y opciones de tráfico disponibles, visita nuestra página de precios. Para casos de uso avanzados y referencia de endpoints, consulta la documentación de la API. También puedes explorar nuestra guía sobre los mejores proxies para web scraping en 2026 para comparaciones de proveedores.

Conclusiones clave

  • Instalación en un comando: pip install proxyhat requests te permite empezar inmediatamente.
  • Usa el SDK por simplicidad: El SDK de Python de ProxyHat gestiona autenticación, reintentos y rotación automáticamente.
  • Elige el tipo de proxy adecuado: Residencial para scraping, datacenter para velocidad, móvil para plataformas sociales.
  • Rotar vs mantener: Usa proxies rotativos para scraping masivo, sesiones sticky para flujos de múltiples pasos.
  • Segmenta geográficamente cuando sea necesario: Especifica país y ciudad para recopilación de datos localizados.
  • Maneja los errores correctamente: Implementa backoff exponencial y lógica de reintentos para fiabilidad en producción.
  • Escala con concurrencia: Usa ThreadPoolExecutor o asyncio para paralelizar solicitudes.
  • Nunca escribas credenciales en el código: Almacena las claves API en variables de entorno.

Preguntas frecuentes

¿Cómo configuro un proxy en Python Requests?

Pasa un diccionario proxies a cualquier método de requests: requests.get(url, proxies={"http": "http://user:pass@host:port", "https": "http://user:pass@host:port"}). El SDK de ProxyHat simplifica esto aún más gestionando la configuración del proxy internamente.

¿Cuál es la diferencia entre proxies rotativos y sticky en Python?

Los proxies rotativos asignan una nueva dirección IP por cada solicitud, lo cual es ideal para scraping a gran escala. Los proxies sticky mantienen la misma IP por un período determinado (ej. 10-30 minutos), necesario para sesiones de login, carritos de compra o navegación paginada donde la consistencia de IP importa.

¿Puedo usar proxies de ProxyHat con asyncio y aiohttp?

Sí. Los proxies de ProxyHat funcionan con cualquier cliente HTTP que soporte configuración de proxy, incluyendo aiohttp, httpx (modo asíncrono) y frameworks basados en asyncio. Pasa la URL del proxy como el parámetro proxy en tu cliente asíncrono.

¿Cómo manejo errores de proxy y timeouts en Python?

Envuelve tus solicitudes en bloques try/except capturando ProxyError, Timeout y ConnectionError. Implementa backoff exponencial (duplicando el tiempo de espera entre reintentos) y establece un conteo máximo de reintentos. El SDK de ProxyHat incluye lógica de reintentos integrada con parámetros configurables.

¿Cuál es la mejor biblioteca de Python para web scraping con proxies?

Para tareas simples, requests con el SDK de ProxyHat es la opción más fácil. Para scraping asíncrono de alta concurrencia, usa httpx o aiohttp. Para crawling complejo con seguimiento de enlaces y extracción de datos, Scrapy con middleware de proxy es la opción más potente. Todos funcionan perfectamente con los proxies de ProxyHat.

¿Listo para empezar?

Accede a más de 50M de IPs residenciales en más de 148 países con filtrado impulsado por IA.

Ver preciosProxies residenciales
← Volver al Blog