Volver al blog

Cómo eludir la limitación de tasa con proxies: arquitectura, rotación de IP y ejemplos de código para desarrolladores

¿El rate limiting bloquea tu parser o cliente API? Analizamos cómo eludir las restricciones de solicitudes utilizando proxies, con ejemplos de código y soluciones arquitectónicas.

📅12 de mayo de 2026
```html

El rate limiting es una de las razones más comunes por las que los scrapers fallan, las integraciones de API se rompen y los scripts automatizados reciben el estado 429 Too Many Requests. El servidor ve demasiadas solicitudes desde una sola IP y simplemente deja de responder. En este artículo, analizaremos cómo construir correctamente la infraestructura sobre proxies para eludir los límites de solicitudes sin bloqueos ni fallos, con ejemplos reales de código en Python y Node.js.

¿Qué es el rate limiting y por qué las demoras comunes no ayudan?

El rate limiting (limitación de frecuencia de solicitudes) es un mecanismo de protección del servidor que limita la cantidad de solicitudes de una sola fuente durante un período de tiempo determinado. La fuente suele ser una dirección IP, pero los sistemas avanzados también consideran tokens de autorización, User-Agent, cookies e incluso patrones de comportamiento.

Cuando tu script excede el límite, el servidor devuelve una de las siguientes respuestas:

  • 429 Too Many Requests — estado HTTP estándar para rate limiting
  • 503 Service Unavailable — a veces se usa en lugar de 429
  • 403 Forbidden — si la IP ya está en la lista negra
  • Respuesta vacía o tiempo de espera — en caso de bloqueo agresivo

El primer pensamiento de la mayoría de los desarrolladores es agregar time.sleep(1) entre solicitudes. Esto solo funciona con límites muy suaves (por ejemplo, 60 solicitudes por minuto). Pero los escenarios reales son más complejos:

Límites reales de plataformas populares:

  • Twitter/X API (gratuito): 500,000 tweets al mes, pero no más de 15 solicitudes cada 15 minutos
  • Google Search: ~100 solicitudes al día desde una IP sin autorización
  • Wildberries, Ozon: rate limiting agresivo — bloqueo después de 30–50 solicitudes por minuto
  • GitHub API: 60 solicitudes/hora sin token, 5000/hora con token
  • Sitios protegidos por Cloudflare: pueden bloquear después de 10–20 solicitudes por minuto

Si necesitas recopilar 100,000 tarjetas de productos de un marketplace o monitorear precios en tiempo real, las demoras simplemente no ayudarán. Se necesita otra arquitectura. Y es aquí donde los proxies se convierten en una necesidad, no en una opción.

Es importante entender: el rate limiting está vinculado a la dirección IP. Si tienes 100 IP diferentes, en realidad tienes 100 "cuotas" independientes. Este es el principio clave para eludir las restricciones a través de proxies.

¿Cómo los proxies resuelven el problema de las restricciones de solicitudes?

El mecanismo es simple: cada solicitud al servidor objetivo se envía desde una dirección IP diferente. Desde el punto de vista del servidor, son diferentes usuarios. La cuota de cada uno de ellos prácticamente no se consume, por lo que no se produce bloqueo.

Consideremos la diferencia entre trabajar sin proxies y con un grupo de proxies en un ejemplo concreto. Supongamos que el servidor permite 10 solicitudes por minuto desde una IP:

Escenario Solicitudes por minuto Bloqueo Tiempo para 10,000 solicitudes
Una IP, sin proxies 10 Sí, después de 10 solicitudes ~16 horas
10 proxies, rotación 100 No ~1.7 horas
100 proxies, rotación 1000 No ~10 minutos

Además de escalar el ancho de banda, los proxies ofrecen varias ventajas al trabajar con rate limiting:

  • Aislamiento de sesiones — si una IP es bloqueada, las demás continúan funcionando
  • Distribución geográfica — las solicitudes provienen de diferentes regiones, lo que reduce la sospecha
  • Sticky sessions — posibilidad de "pegarse" a una IP para escenarios de múltiples pasos (autenticación + acción)
  • Control de carga — se pueden dosificar las solicitudes a cada IP, sin exceder el límite

¿Qué tipo de proxy elegir para tu tarea?

No todos los proxies son igualmente efectivos contra el rate limiting. La elección del tipo depende del sitio objetivo, el volumen de solicitudes y el presupuesto. Analicemos tres tipos principales:

Proxies residenciales

Estas son direcciones IP de usuarios domésticos reales. Parecen tráfico de internet normal y rara vez son bloqueadas. Los proxies residenciales son la mejor opción para sitios con protección agresiva: marketplaces (Wildberries, Ozon), redes sociales, recursos protegidos por Cloudflare. La principal desventaja es su precio más alto en comparación con los de centros de datos.

Proxies móviles

Direcciones IP de operadores móviles (3G/4G/5G). Su característica es que una IP puede ser utilizada por miles de abonados reales simultáneamente, por lo que los sitios no quieren bloquear tales direcciones. Los proxies móviles muestran los mejores resultados donde los residenciales ya comienzan a ser bloqueados, por ejemplo, en scraping de Instagram de alta frecuencia o trabajando con APIs de plataformas que analizan el tipo de conexión.

Proxies de centros de datos

IP rápidas y baratas de centros de datos. Son ideales para scraping de sitios sin protección seria: APIs abiertas, agregadores de noticias, bases de datos públicas. Para tareas con rate limiting, se necesitan más (ya que suelen caer en listas negras), pero con la rotación adecuada, manejan grandes volúmenes de solicitudes de manera efectiva. Más detalles en la página de proxies de centros de datos.

Tipo de proxy Anonimato Velocidad Precio Mejor escenario
Residenciales Muy alta Media $$ Marketplaces, redes sociales, Cloudflare
Móviles Máxima Media $$$ API de Instagram, scraping de alta frecuencia
Centros de datos Media Alta $ APIs abiertas, datos públicos

Estrategias de rotación de IP: por solicitud, sesiones pegajosas, round-robin

El simple hecho de tener proxies no resuelve el problema; es importante gestionarlos correctamente. Existen varias estrategias de rotación, cada una adecuada para sus propios escenarios.

Rotación por solicitud (nueva IP en cada solicitud)

Cada solicitud HTTP se envía a través de una nueva dirección IP. Esta es la estrategia más agresiva para eludir el rate limiting: el servidor no tiene tiempo para acumular un contador para una sola IP. Es adecuada para:

  • Scraping de tarjetas de productos (cada tarjeta es una solicitud separada)
  • Recopilación de datos de motores de búsqueda
  • Cualquier solicitud sin estado que no requiera sesión

Sesiones pegajosas (IP fija por sesión)

Una IP se utiliza durante toda la sesión (generalmente de 1 a 30 minutos). Esto es crítico para escenarios donde se requiere autenticación: iniciar sesión, realizar una acción, cerrar sesión. Si la IP cambia entre pasos, el servidor puede bloquear la sesión como sospechosa.

Round-robin con límite de solicitudes por IP

La estrategia más precisa. Conoces el límite del servidor (por ejemplo, 10 solicitudes por minuto) y distribuyes las solicitudes entre el grupo de proxies de manera que cada IP nunca supere este umbral. Requiere implementar una cola teniendo en cuenta el tiempo de la última solicitud para cada IP.

Fórmula para calcular el número necesario de proxies:

N proxies = (Velocidad objetivo de solicitudes/min) ÷ (Límite del servidor/min por IP)
Ejemplo: necesitas 500 solicitudes/min, el límite del servidor es 10/min → necesitas al menos 50 proxies. Agrega un 20% de reserva en caso de bloqueos: en total, 60 proxies.

Ejemplos de código en Python: requests, aiohttp, Scrapy

Pasemos a la práctica. A continuación, plantillas listas para tres de las herramientas de Python más populares.

1. requests + rotación de proxies manualmente

La opción más simple es una lista de proxies y una selección aleatoria para cada solicitud:

import requests
import random
import time

PROXIES = [
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
    # ... agrega la cantidad necesaria
]

def get_random_proxy():
    proxy = random.choice(PROXIES)
    return {"http": proxy, "https": proxy}

def fetch_with_retry(url, max_retries=3):
    for attempt in range(max_retries):
        proxy = get_random_proxy()
        try:
            response = requests.get(
                url,
                proxies=proxy,
                timeout=10,
                headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"}
            )
            if response.status_code == 429:
                print(f"Limitado por tasa en {proxy}, cambiando...")
                time.sleep(1)
                continue
            return response
        except requests.RequestException as e:
            print(f"Intento {attempt+1} fallido: {e}")
            time.sleep(2)
    return None

# Uso
urls = ["https://example.com/item/1", "https://example.com/item/2"]
for url in urls:
    result = fetch_with_retry(url)
    if result:
        print(f"OK: {url} — {len(result.text)} bytes")

2. Grupo inteligente de proxies considerando el rate limit

Una opción más avanzada es la clase ProxyPool, que rastrea el tiempo de último uso de cada IP y no excede el límite establecido:

import requests
import time
from collections import defaultdict
from threading import Lock

class ProxyPool:
    def __init__(self, proxies, rate_limit=10, window=60):
        """
        proxies: lista de cadenas del tipo 'http://user:pass@host:port'
        rate_limit: máximo de solicitudes desde una IP durante window segundos
        window: ventana de tiempo en segundos
        """
        self.proxies = proxies
        self.rate_limit = rate_limit
        self.window = window
        self.usage = defaultdict(list)  # proxy -> [timestamps]
        self.lock = Lock()

    def get_available_proxy(self):
        now = time.time()
        with self.lock:
            for proxy in self.proxies:
                # Limpiamos las marcas obsoletas
                self.usage[proxy] = [
                    t for t in self.usage[proxy]
                    if now - t < self.window
                ]
                if len(self.usage[proxy]) < self.rate_limit:
                    self.usage[proxy].append(now)
                    return {"http": proxy, "https": proxy}
        return None  # Todos los proxies han agotado el límite

    def fetch(self, url, **kwargs):
        proxy = self.get_available_proxy()
        if proxy is None:
            print("Todos los proxies limitados por tasa, esperando...")
            time.sleep(5)
            return self.fetch(url, **kwargs)
        
        try:
            response = requests.get(url, proxies=proxy, timeout=10, **kwargs)
            return response
        except requests.RequestException as e:
            print(f"La solicitud falló: {e}")
            return None

# Uso
pool = ProxyPool(
    proxies=[
        "http://user:[email protected]:8080",
        "http://user:[email protected]:8080",
    ],
    rate_limit=10,  # 10 solicitudes por minuto por IP
    window=60
)

for i in range(100):
    r = pool.fetch(f"https://example.com/page/{i}")
    if r:
        print(f"Página {i}: {r.status_code}")

3. aiohttp para scraping asíncrono

El enfoque asíncrono permite utilizar decenas de proxies en paralelo sin bloquear los hilos:

import asyncio
import aiohttp
import itertools

PROXIES = [
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
]

proxy_cycle = itertools.cycle(PROXIES)

async def fetch(session, url, proxy):
    try:
        async with session.get(
            url,
            proxy=proxy,
            timeout=aiohttp.ClientTimeout(total=10)
        ) as response:
            if response.status == 429:
                await asyncio.sleep(2)
                return None
            return await response.text()
    except Exception as e:
        print(f"Error: {e}")
        return None

async def main(urls):
    connector = aiohttp.TCPConnector(limit=50)
    async with aiohttp.ClientSession(connector=connector) as session:
        tasks = [
            fetch(session, url, next(proxy_cycle))
            for url in urls
        ]
        results = await asyncio.gather(*tasks)
        return results

urls = [f"https://example.com/item/{i}" for i in range(200)]
results = asyncio.run(main(urls))
print(f"Recopilados: {sum(1 for r in results if r is not None)} páginas")

4. Scrapy con rotación a través de middleware

Para Scrapy existe una solución lista: scrapy-rotating-proxies. Pero se puede escribir un middleware propio:

# middlewares.py
import random

class RotatingProxyMiddleware:
    def __init__(self, proxies):
        self.proxies = proxies

    @classmethod
    def from_crawler(cls, crawler):
        return cls(proxies=crawler.settings.getlist("PROXY_LIST"))

    def process_request(self, request, spider):
        proxy = random.choice(self.proxies)
        request.meta["proxy"] = proxy

    def process_response(self, request, response, spider):
        if response.status == 429:
            spider.logger.warning(f"Limitado por tasa, proxy: {request.meta.get('proxy')}")
            # Se puede agregar lógica para excluir el proxy problemático
        return response

# settings.py
PROXY_LIST = [
    "http://user:[email protected]:8080",
    "http://user:[email protected]:8080",
]
DOWNLOADER_MIDDLEWARES = {
    "myproject.middlewares.RotatingProxyMiddleware": 350,
}
AUTOTHROTTLE_ENABLED = True
AUTOTHROTTLE_TARGET_CONCURRENCY = 10

Ejemplos de código en Node.js: axios, got, Puppeteer

Node.js es una elección popular para la automatización de navegadores y el trabajo con APIs. Aquí tienes patrones listos para trabajar con proxies.

1. axios con rotación de proxies

const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');

const proxies = [
  'http://user:[email protected]:8080',
  'http://user:[email protected]:8080',
  'http://user:[email protected]:8080',
];

let proxyIndex = 0;

function getNextProxy() {
  const proxy = proxies[proxyIndex % proxies.length];
  proxyIndex++;
  return proxy;
}

async function fetchWithProxy(url, retries = 3) {
  for (let i = 0; i < retries; i++) {
    const proxyUrl = getNextProxy();
    const agent = new HttpsProxyAgent(proxyUrl);
    
    try {
      const response = await axios.get(url, {
        httpsAgent: agent,
        httpAgent: agent,
        timeout: 10000,
        headers: {
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
        },
      });
      return response.data;
    } catch (error) {
      if (error.response?.status === 429) {
        console.log(`Limitado por tasa, cambiando proxy...`);
        await new Promise(r => setTimeout(r, 1000));
        continue;
      }
      console.error(`Intento ${i + 1} fallido:`, error.message);
    }
  }
  return null;
}

// Uso
(async () => {
  const urls = Array.from({length: 50}, (_, i) => `https://example.com/item/${i}`);
  
  const results = await Promise.allSettled(
    urls.map(url => fetchWithProxy(url))
  );
  
  const successful = results.filter(r => r.status === 'fulfilled' && r.value).length;
  console.log(`Éxito: ${successful}/${urls.length}`);
})();

2. Puppeteer con proxy y elusión del rate limiting

Para sitios con renderizado JavaScript y protección Cloudflare, se necesita un navegador sin cabeza:

const puppeteer = require('puppeteer');

const proxies = [
  'proxy1.example.com:8080',
  'proxy2.example.com:8080',
];

async function scrapeWithProxy(url, proxyHost) {
  const browser = await puppeteer.launch({
    args: [
      `--proxy-server=${proxyHost}`,
      '--no-sandbox',
      '--disable-setuid-sandbox',
    ],
    headless: true,
  });

  const page = await browser.newPage();
  
  // Autenticación del proxy
  await page.authenticate({
    username: 'user',
    password: 'pass',
  });

  // Establecer un User-Agent realista
  await page.setUserAgent(
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
  );

  try {
    await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 });
    
    // Comprobar el rate limit
    const status = await page.evaluate(() => document.title);
    if (status.includes('429') || status.includes('Too Many')) {
      console.log('Limitado por tasa, es necesario cambiar el proxy');
      return null;
    }
    
    const data = await page.evaluate(() => {
      return document.querySelector('.price')?.textContent || null;
    });
    
    return data;
  } finally {
    await browser.close();
  }
}

// Rotación por tareas
(async () => {
  const urls = ['https://example.com/product/1', 'https://example.com/product/2'];
  
  for (let i = 0; i < urls.length; i++) {
    const proxy = proxies[i % proxies.length];
    const result = await scrapeWithProxy(urls[i], proxy);
    console.log(`${urls[i]}: ${result}`);
    await new Promise(r => setTimeout(r, 500)); // pequeña demora
  }
})();

Técnicas avanzadas: encabezados, fingerprint, eludir Cloudflare

Cambiar la IP es una condición necesaria, pero no siempre suficiente. Los sistemas de protección modernos analizan decenas de parámetros de la solicitud. Analicemos qué más se debe tener en cuenta.

Encabezados HTTP: conjunto mínimo obligatorio

Una solicitud sin encabezados normales parece un bot incluso al cambiar la IP. Siempre agrega:

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
    "Accept-Language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
    "Accept-Encoding": "gzip, deflate, br",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "none",
    "Cache-Control": "max-age=0",
}

Manejo del encabezado Retry-After

Al responder 429, el servidor a menudo indica cuánto tiempo hay que esperar. Manejar correctamente este encabezado permite no desperdiciar solicitudes:

def handle_rate_limit(response):
    if response.status_code == 429:
        retry_after = response.headers.get("Retry-After")
        if retry_after:
            wait_time = int(retry_after)
            print(f"Limitado por tasa. Esperando {wait_time} segundos...")
            time.sleep(wait_time + 1)  # +1 segundo de buffer
        else:
            # Retraso exponencial si no hay encabezado
            time.sleep(min(2 ** attempt, 60))
        return True
    return False

Fingerprinting TLS y cómo eludirlo

Los sistemas avanzados (Cloudflare, Akamai, PerimeterX) analizan el fingerprint TLS: una "huella" única de tu conexión TLS. La biblioteca estándar requests tiene un fingerprint fácilmente reconocible. Soluciones:

  • curl_cffi (Python) — emula el fingerprint de Chrome/Firefox a nivel TLS
  • tls-client (Go/Python) — herramienta similar con soporte para diferentes perfiles de navegador
  • Playwright/Puppeteer — navegador real, fingerprint ideal por defecto
# pip install curl-cffi
from curl_cffi import requests as cffi_requests

response = cffi_requests.get(
    "https://cloudflare-protected-site.com/api/data",
    impersonate="chrome120",  # Emulando Chrome 120
    proxies={"https": "http://user:[email protected]:8080"}
)
print(response.json())

Gestión de cookies y sesiones

Si el sitio utiliza cookies para rastrear sesiones, cambiar la IP sin cambiar las cookies es inútil. Al cambiar de proxy, siempre crea una nueva sesión:

import requests

def create_fresh_session(proxy_url):
    """Creamos una nueva sesión con cookies limpias para cada proxy"""
    session = requests.Session()
    session.proxies = {"http": proxy_url, "https": proxy_url}
    session.headers.update({
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)...",
    })
    # Las cookies no se transfieren de la sesión anterior
    return session

# Para cada nueva IP — nueva sesión
for proxy in proxies:
    session = create_fresh_session(proxy)
    response = session.get("https://example.com/protected-page")
    # Procesar la respuesta...

Errores comunes al trabajar con proxies y rate limiting

Incluso con proxies configurados correctamente, los desarrolladores a menudo cometen los mismos errores. Aquí están los errores más comunes y cómo evitarlos.

Lista de verificación: qué verificar antes de iniciar el scraper

  • ☐ Se han agregado encabezados HTTP realistas (User-Agent, Accept, Accept-Language)
  • ☐ Al cambiar de proxy, se crea una nueva sesión (nuevas cookies)
  • ☐ Se manejan los estados 429, 503, 403 con lógica de reintento
  • ☐ Se implementa un retraso entre solicitudes (al menos 100–500 ms)
  • ☐ La cantidad de proxies corresponde a la velocidad objetivo de solicitudes
  • ☐ Se verifica el funcionamiento de los proxies antes de iniciar (chequeo de salud)
  • ☐ Se registran errores y estadísticas para cada proxy
  • ☐ Se configura un tiempo de espera para las solicitudes (no más de 15–30 segundos)

Error 1: Uso de proxies "muertos"

Siempre verifica los proxies antes de agregarlos al grupo y periódicamente durante su uso. Un proxy no funcional en el ciclo significa solicitudes perdidas y tiempos de espera:

def check_proxy(proxy_url, test_url="https://httpbin.org/ip", timeout=5):
    try:
        r = requests.get(
            test_url,
            proxies={"http": proxy_url, "https": proxy_url},
            timeout=timeout
        )
        return r.status_code == 200
    except:
        return False

# Filtrar proxies funcionales antes de iniciar
working_proxies = [p for p in PROXIES if check_proxy(p)]
print(f"Proxies funcionales: {len(working_proxies)}/{len(PROXIES)}")

Error 2: Ignorar el tipo de protocolo

Los proxies HTTP no pueden proxyar tráfico HTTPS directamente (solo a través de CONNECT). Los proxies SOCKS5 funcionan a nivel de transporte y admiten cualquier protocolo. Para la mayoría de los sitios modernos, utiliza proxies SOCKS5 o HTTPS:

# Proxies SOCKS5 en requests (requiere pip install requests[socks])
proxies = {
    "http": "socks5://user:[email protected]:1080",
    "https": "socks5://user:[email protected]:1080",
}

# Proxies HTTPS
proxies = {
    "http": "https://user:[email protected]:8080",
    "https": "https://user:[email protected]:8080",
}

Error 3: Falta de retroceso exponencial

Si después de un 429 repites la solicitud de inmediato, solo empeoras la situación. La estrategia correcta es un retraso exponencial con jitter (desviación aleatoria):

import random

def exponential_backoff(attempt, base=1, max_wait=60):
    """
    attempt: número de intento (comenzando desde 0)
    base: retraso base en segundos
    max_wait: retraso máximo
    """
    wait = min(base * (2 ** attempt), max_wait)
    # Jitter ±25% para prevenir el thundering herd
    jitter = wait * 0.25 * random.uniform(-1, 1)
    return wait + jitter

# Uso en la lógica de reintento
for attempt in range(5):
    response = requests.get(url, proxies=proxy)
    if response.status_code == 429:
        wait = exponential_backoff(attempt)
        print(f"Limitado por tasa. Esperando {wait:.1f}s (intento {attempt+1})")
        time.sleep(wait)
    else:
        break

Error 4: Un hilo para todos los proxies

Si tienes 50 proxies pero un solo hilo de ejecución, solo utilizas un proxy a la vez. Utiliza ThreadPoolExecutor o un enfoque asíncrono para utilizar todo el grupo en paralelo:

from concurrent.futures import ThreadPoolExecutor, as_completed

def fetch_url(args):
    url, proxy = args
    try:
        r = requests.get(url, proxies={"https": proxy}, timeout=10)
        return url, r.status_code, len(r.text)
    except Exception as e:
        return url, None, str(e)

# Utilizar todos los proxies en paralelo
tasks = [(url, proxies[i % len(proxies)]) for i, url in enumerate(urls)]

with ThreadPoolExecutor(max_workers=len(proxies)) as executor:
    futures = {executor.submit(fetch_url, task): task for task in tasks}
    for future in as_completed(futures):
        url, status, size = future.result()
        print(f"{url}: {status} ({size})")

Conclusión y recomendaciones

El rate limiting es un problema que se puede resolver si se aborda de manera sistemática. Conclusiones clave de esta guía:

  • Grupo de proxies, no un solo proxy — la unidad mínima para un trabajo serio. La cantidad de proxies se determina con la fórmula: velocidad objetivo ÷ límite del servidor por IP.
  • La estrategia de rotación es importante — por solicitud para solicitudes sin estado, sesiones pegajosas para escenarios autenticados.
  • La IP no es el único parámetro — los encabezados, cookies, fingerprint TLS y patrones de comportamiento también son analizados por los sistemas de protección.
  • Maneja correctamente el 429 — retroceso exponencial, encabezado Retry-After, cambio de proxy en caso de bloqueo.
  • El tipo de proxy depende del objetivo — proxies de centros de datos para APIs abiertas, residenciales para marketplaces, móviles para máxima protección.

Si trabajas con scraping de marketplaces (Wildberries, Ozon), recopilación de datos de APIs protegidas o automatización a altas velocidades, te recomendamos comenzar con proxies residenciales: ofrecen un equilibrio óptimo entre anonimato y velocidad, y sus direcciones IP rara vez caen en listas negras. Para tareas donde se necesita la máxima resistencia a bloqueos con alta frecuencia de solicitudes, considera proxies móviles — sus IP son compartidas por miles de usuarios reales, lo que hace que el bloqueo sea extremadamente indeseable para cualquier sitio.

```