← Volver al blog

Análisis de imágenes para conjuntos de datos de CV: cuánto tráfico se necesita y qué proxies elegir

Analizamos cuánto tráfico se necesita realmente para recopilar miles de imágenes para entrenar modelos de CV, qué proxies utilizar y cómo escribir un parser que no sea bloqueado.

📅1 de noviembre de 2026

Recopilar miles de imágenes para entrenar un modelo de visión por computadora es una tarea que casi siempre se enfrenta a dos problemas: bloqueos por parte de la fuente de datos (Google Images, Pinterest, marketplaces, sitios de stock) y un consumo de tráfico inesperadamente alto. Una IP rápidamente se va a la lista negra, y la factura por el tráfico de proxies puede superar el costo de la propia anotación del conjunto de datos. En este artículo, analizaremos cómo diseñar un analizador de imágenes que no pierda datos debido a bloqueos y cómo calcular el presupuesto para el tráfico por adelantado.

¿Por qué usar proxies al recopilar imágenes para CV?

Los conjuntos de datos para visión por computadora rara vez se recopilan de una sola fuente. Por lo general, es una combinación de resultados de búsqueda de imágenes, tarjetas de productos en marketplaces, bancos de fotos, redes sociales y API abiertas. Casi todas estas fuentes imponen restricciones en la cantidad de solicitudes desde una sola IP: Google Images muestra un captcha después de unas pocas centenas de solicitudes consecutivas, Pinterest bloquea temporalmente el acceso a la API, y Wildberries y Ozon devuelven tarjetas vacías o redirigen a una página de verificación ante actividad sospechosa.

Sin proxies, te enfrentas a un límite de unas pocas centenas o miles de imágenes al día desde una sola dirección. Si necesitas un conjunto de datos de 50,000 a 500,000 imágenes (y esa es la cantidad que generalmente se requiere para redes convolucionales y transformadores en tareas de clasificación y detección), sin un grupo distribuido de direcciones IP, es físicamente imposible recopilarlo en un tiempo razonable: o te encontrarás constantemente con bloqueos, o obtendrás una muestra muy sesgada debido a las restricciones de tiempo y geolocalización.

La segunda razón es la diversidad geográfica de los datos. Si el modelo debe reconocer objetos de manera uniforme independientemente de la región de captura (por ejemplo, señales de tráfico en diferentes países o productos en marketplaces locales), el analizador debe conectarse con IP de diferentes países. Un centro de datos con una única IP de salida no proporcionará tal diversidad.

¿Cuánto tráfico se consume realmente en un conjunto de datos?

El consumo de tráfico al recopilar imágenes a menudo se subestima. No se trata solo del peso de las imágenes en sí: las páginas HTML, los paquetes JS, las vistas previas, los píxeles de seguimiento y el CSS también se transmiten a través de proxies si el analizador no está configurado específicamente para las URL necesarias.

Tipo de contenido Peso promedio Tráfico por 10,000 unidades
Vista previa/thumbnail (150–300 px) 15–40 KB ~250 MB
Foto de resolución media (800–1200 px) 80–200 KB ~1.4 GB
Foto de alta resolución (2000+ px) 400 KB – 1.5 MB ~9.5 GB
Página HTML de la tarjeta de producto (sin imágenes) 150–400 KB ~2.7 GB

En la práctica, si recopilas 100,000 imágenes de resolución media junto con las páginas de las tarjetas (para extraer anotaciones — categorías, cuadros, atributos), el consumo total de tráfico generalmente se encuentra en el rango de 25–45 GB. Si necesitas imágenes de alta resolución para tareas de detección de objetos pequeños, calcula entre 80–150 GB para las mismas 100,000 unidades. Estas cifras deben tenerse en cuenta al elegir un plan de proxies por adelantado, y no después de los hechos.

Datacenter, residencial y móvil: ¿qué elegir?

Para la recopilación de imágenes, hay tres parámetros importantes: velocidad, costo del tráfico y resistencia a bloqueos. Estos parámetros varían significativamente entre los diferentes tipos de proxies.

Parámetro Datacenter Residencial Móvil
Velocidad Alta Media Baja-media
Resistencia a bloqueos Baja Alta Muy alta
Costo del tráfico Bajo Media-alta Alta
Adecuado para APIs abiertas, stocks sin protección estricta Google Images, Pinterest, marketplaces Redes sociales con protección anti-bot estricta

Para la mayoría de las tareas de recopilación de imágenes, el equilibrio óptimo lo ofrecen proxies residenciales — las IP parecen usuarios normales, por lo que los sistemas anti-bot de los marketplaces y motores de búsqueda de imágenes activan menos frecuentemente el captcha. Si la fuente es un banco de fotos abierto o una API sin límites estrictos, es más barato usar proxies de centros de datos — son más rápidos y permiten manejar grandes volúmenes de tráfico a un costo por GB más bajo. Y para la recopilación de imágenes de aplicaciones móviles o redes sociales con protección anti-bot avanzada, son más adecuados los proxies móviles — utilizan IP reales de operadores de telecomunicaciones y casi nunca son bloqueados.

Analizador básico en requests con rotación de proxies

Para comenzar, un simple script sincrónico en requests con rotación de proxies en cada solicitud o después de un número determinado de solicitudes funcionará. A continuación se muestra un ejemplo de descarga de imágenes a partir de una lista de URL con verificación del tipo de contenido y limitación del tamaño del archivo, para no descargar accidentalmente un archivo pesado de un formato incorrecto.

import requests
import itertools
import hashlib
import os

PROXIES = [
    "http://user:[email protected]:10000",
    "http://user:[email protected]:10000",
    "http://user:[email protected]:10000",
]
proxy_cycle = itertools.cycle(PROXIES)

HEADERS = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    "Accept": "image/avif,image/webp,image/*,*/*;q=0.8",
}

def download_image(url, save_dir="dataset", max_size_mb=10, timeout=15):
    proxy = next(proxy_cycle)
    proxies = {"http": proxy, "https": proxy}
    try:
        resp = requests.get(url, headers=HEADERS, proxies=proxies, timeout=timeout, stream=True)
        resp.raise_for_status()

        content_type = resp.headers.get("Content-Type", "")
        if "image" not in content_type:
            return None

        content_length = int(resp.headers.get("Content-Length", 0))
        if content_length > max_size_mb * 1024 * 1024:
            return None

        file_hash = hashlib.md5(url.encode()).hexdigest()
        ext = content_type.split("/")[-1].split(";")[0]
        filepath = os.path.join(save_dir, f"{file_hash}.{ext}")

        os.makedirs(save_dir, exist_ok=True)
        with open(filepath, "wb") as f:
            for chunk in resp.iter_content(chunk_size=8192):
                f.write(chunk)

        return filepath
    except requests.exceptions.RequestException as e:
        print(f"Error al {url} a través de {proxy}: {e}")
        return None

El punto clave es verificar Content-Length antes de descargar el cuerpo de la respuesta. Esto ahorra tráfico, filtrando archivos demasiado pesados antes de la carga completa. La rotación de proxies a través de itertools.cycle distribuye uniformemente la carga entre las IP, reduciendo el riesgo de que una dirección específica sea bloqueada.

Recopilación asíncrona a través de aiohttp

Un script sincrónico en requests es adecuado para unos pocos miles de imágenes, pero para conjuntos de datos de 50,000 archivos o más, se necesita asincronía; de lo contrario, la recopilación se extenderá durante días. aiohttp junto con un semáforo para limitar el paralelismo es una opción viable para decenas de miles de tareas simultáneas sin sobrecargar el grupo de proxies.

import asyncio
import aiohttp
import itertools

PROXIES = [
    "http://user:[email protected]:10000",
    "http://user:[email protected]:10000",
]
proxy_cycle = itertools.cycle(PROXIES)
sem = asyncio.Semaphore(50)  # limitación de solicitudes paralelas

async def fetch_image(session, url, idx):
    proxy = next(proxy_cycle)
    async with sem:
        try:
            async with session.get(url, proxy=proxy, timeout=15) as resp:
                if resp.status != 200:
                    return
                content_type = resp.headers.get("Content-Type", "")
                if "image" not in content_type:
                    return
                data = await resp.read()
                with open(f"dataset/{idx}.jpg", "wb") as f:
                    f.write(data)
        except Exception as e:
            print(f"Error {url}: {e}")

async def main(urls):
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_image(session, url, i) for i, url in enumerate(urls)]
        await asyncio.gather(*tasks)

# asyncio.run(main(url_list))

Un semáforo de 50 conexiones simultáneas es un punto de partida. Si los proxies residenciales soportan la carga sin un aumento en los errores 429 y tiempos de espera, se puede aumentar gradualmente a 100-150. Lo principal es monitorear el porcentaje de solicitudes fallidas: si aumenta por encima del 5-7%, es mejor reducir el paralelismo en lugar de aumentar el grupo de proxies indefinidamente.

Scrapy + middleware de proxies para recopilación a gran escala

Para la recopilación de conjuntos de datos en producción con cola integrada, reintentos y deduplicación de URL, es más conveniente utilizar Scrapy con ImagesPipeline. Esta misma descarga las imágenes, verifica su validez a través de PIL y puede generar vistas previas de diferentes tamaños.

# settings.py
ITEM_PIPELINES = {
    'scrapy.pipelines.images.ImagesPipeline': 1,
}
IMAGES_STORE = 'dataset_images'
IMAGES_MIN_HEIGHT = 200
IMAGES_MIN_WIDTH = 200

DOWNLOADER_MIDDLEWARES = {
    'myproject.middlewares.ProxyRotationMiddleware': 350,
}

CONCURRENT_REQUESTS = 32
DOWNLOAD_DELAY = 0.5
RETRY_TIMES = 3
# middlewares.py
import random

class ProxyRotationMiddleware:
    PROXIES = [
        "http://user:[email protected]:10000",
        "http://user:[email protected]:10000",
        "http://user:[email protected]:10000",
    ]

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

Los parámetros IMAGES_MIN_HEIGHT y IMAGES_MIN_WIDTH eliminan automáticamente íconos pequeños y sprites que contaminan el conjunto de datos y desperdician tráfico. Un DOWNLOAD_DELAY de 0.5 segundos reduce la frecuencia de solicitudes desde un proxy, lo que disminuye la proporción de captchas en fuentes con monitoreo anti-fraude estricto como Pinterest.

Cómo reducir el consumo de tráfico

El tráfico a través de proxies generalmente se cobra por volumen, por lo que cualquier optimización ahorra directamente presupuesto. Aquí hay algunos métodos efectivos:

  • Solicita vistas previas, no originales, si para el entrenamiento es suficiente una resolución de 512–1024 px — la mayoría de las fuentes devuelven la imagen del tamaño necesario a través de una URL separada o un parámetro de consulta.
  • Filtra por Content-Length antes de descargar el cuerpo — una solicitud HEAD o la lectura de encabezados de un GET en streaming permite descartar archivos demasiado pesados sin gastar tráfico en su carga.
  • Desactiva la carga de recursos adicionales, si el analizador funciona a través de un navegador sin cabeza: bloquea CSS, fuentes y scripts de seguimiento, dejando solo HTML e imágenes necesarias.
  • Deduplica URL antes de la solicitud, y no después de la descarga — las imágenes idénticas en diferentes páginas de productos (por ejemplo, en Wildberries) no necesitan descargarse de nuevo.
  • Utiliza un caché local de respuestas durante las ejecuciones repetidas del analizador durante la depuración, para no gastar tráfico a través de proxies en cada ejecución de prueba del código.

Errores comunes, 403 y límite de tasa

Al recopilar imágenes en grandes volúmenes, el analizador inevitablemente se encontrará con respuestas 403, 429 y redirecciones temporales a páginas de verificación. El manejo adecuado de estos códigos ahorra tanto tráfico como el grupo de proxies.

Código/síntoma Razón Qué hacer
403 Forbidden IP en la lista negra de la fuente Rotación de proxies, cambio de User-Agent
429 Too Many Requests Se ha superado el límite de solicitudes por minuto Aumentar DOWNLOAD_DELAY, reducir paralelismo
Redirección a captcha El análisis de comportamiento sospechó de un bot Cambiar a IP residenciales/móviles
Content-Length vacío Respuesta chunked o un placeholder en lugar de una imagen Verificar el tamaño real de los bytes descargados

Es recomendable registrar la proporción de solicitudes exitosas por cada proxy. Si una IP específica da consistentemente 403 más que las demás, elimínala de la rotación automáticamente, sin esperar a que afecte la estadística general de bloqueos en todo el grupo.

Cálculo del presupuesto para tráfico de proxies

Antes de iniciar la recopilación, es útil estimar el volumen de tráfico por adelantado, en lugar de calcularlo después. La fórmula es simple: número de imágenes × peso promedio del archivo × coeficiente de gastos generales (HTML, encabezados, solicitudes repetidas debido a errores — generalmente 1.3–1.6).

Ejemplo de cálculo para un conjunto de datos de 200,000 imágenes de resolución media (~150 KB) con análisis de tarjetas de productos: 200,000 × 150 KB = 30 GB de peso neto de imágenes. Teniendo en cuenta las páginas HTML y las solicitudes repetidas debido a bloqueos temporales (coeficiente 1.5), el consumo total es de aproximadamente 45 GB. Si algunas fuentes requieren IP móviles debido a la protección anti-bot, considera esto en el grupo de proxies por separado, ya que el tráfico en IP móviles generalmente es más caro que en residenciales o de centros de datos.

Una buena práctica es recopilar un lote piloto de 1,000–2,000 imágenes, medir el consumo real de tráfico y el porcentaje de errores, y luego extrapolarlo al volumen total planificado del conjunto de datos. Esto es más preciso que cualquier cálculo teórico, ya que tiene en cuenta la especificidad de la fuente concreta.

Conclusión

La recopilación de imágenes para entrenar modelos de visión por computadora es una tarea en la intersección de la ingeniería de datos y la gestión adecuada de la infraestructura de red. La arquitectura correcta del analizador (asincronía, filtrado por Content-Length, deduplicación de URL) ahorra tráfico, y una elección bien pensada de proxies determina si recopilarás el volumen necesario del conjunto de datos en días o en semanas de bloqueos constantes.

Si las fuentes de datos utilizan protección anti-bot avanzada — motores de búsqueda de imágenes, marketplaces, redes sociales — comienza con proxies residenciales: ofrecen el mejor equilibrio entre resistencia a bloqueos y costo de tráfico. Para APIs abiertas y bancos de fotos sin límites estrictos, tiene sentido ahorrar en proxies de centros de datos, y para las aplicaciones móviles más protegidas, conectar proxies móviles para la parte final, más compleja de la recopilación.