Si estás scrapeando Wildberries, Ozon o cualquier otro sitio a través de la carga de páginas HTML completas, estás pagando por el tráfico de proxies de 5 a 10 veces más de lo que podrías. Cada página de un producto es de 200 a 800 KB de marcado, scripts y estilos, de los cuales realmente solo necesitas unos pocos campos: precio, disponibilidad, calificación. En este artículo analizamos cómo encontrar el API oculto del sitio y obtener los mismos datos directamente, en un formato JSON compacto.
Por qué el scraping de HTML consume tráfico de proxies
Cuando un scraper carga una página a través de una solicitud HTTP normal o a través de un navegador sin cabeza (Selenium, Puppeteer, Playwright), el servidor devuelve un documento HTML completo: marcado, scripts en línea, estilos, a veces imágenes en base64 y cientos de líneas de JSON con datos para widgets publicitarios que no necesitas. La tarjeta de producto promedio en Wildberries pesa entre 300 y 600 KB, en Ozon hasta 800 KB, si se cuentan todos los recursos relacionados (CSS, fuentes, rastreadores).
Si monitoreas 10,000 productos una vez al día a través de 3 sesiones de proxies, esto fácilmente se traduce en decenas de gigabytes de tráfico al mes. Los proxies residenciales y móviles generalmente se venden por tráfico, por lo que cada megabyte adicional representa un gasto directo. Mientras tanto, los datos reales que necesitas — precio, descuento, stock, calificación — ocupan en la respuesta JSON entre 1 y 5 KB. La diferencia es de 100 a 200 veces en volumen por producto, y teniendo en cuenta los gastos generales de renderizado del navegador, el ahorro de tiempo y CPU es aún mayor.
Un problema adicional del scraping HTML es su fragilidad. Los sitios de marketplaces cambian regularmente el diseño, las clases CSS, la estructura del DOM. Cada cambio de este tipo rompe el scraper construido sobre XPath o selectores CSS. El API interno cambia con mucha menos frecuencia, porque de él depende el funcionamiento de la aplicación móvil y del frontend del sitio al mismo tiempo.
Qué es un API oculto y de dónde proviene
Casi cada sitio moderno es una SPA (Single Page Application) o una aplicación híbrida, donde el navegador primero carga el "esqueleto" de la página y luego, a través de JavaScript, hace solicitudes adicionales al API interno para obtener datos reales: precios, existencias, reseñas, recomendaciones. Estas solicitudes se llaman APIs ocultas o internas — no están documentadas públicamente, pero están completamente abiertas en el tráfico del navegador.
Técnicamente, estos son generalmente endpoints REST o GraphQL que devuelven datos en formato JSON. Por ejemplo, en Wildberries, la tarjeta de producto se carga a través de solicitudes del tipo card.wb.ru y wbx-content-v2.wbstatic.net, mientras que los precios y existencias se obtienen mediante una solicitud separada a basket-01.wb.ru y dominios similares. En Ozon, la lógica es similar: el frontend accede al API interno de composer, que agrega datos de microservicios.
Es importante entender: el uso de tal API no se considera formalmente un hackeo — simplemente estás repitiendo las mismas solicitudes que hace un navegador normal del usuario. Pero los sitios protegen estos endpoints a través de sistemas anti-bots, por lo que se necesita una imitación cuidadosa del comportamiento de un cliente real, incluyendo proxies de calidad.
Cómo encontrar un API oculto a través de DevTools
Puedes encontrar un API interno sin escribir una sola línea de código, utilizando las herramientas integradas del navegador Chrome o Firefox. Aquí tienes un algoritmo paso a paso:
- Abre la página del producto deseado en Chrome, presiona F12 y ve a la pestaña Network.
- En el filtro de solicitudes, selecciona el tipo Fetch/XHR — así filtrarás la carga de imágenes, fuentes y estáticos.
- Actualiza la página (F5) y observa la lista de solicitudes que aparecieron después de cargar el esqueleto de la página.
- Encuentra la solicitud en cuya respuesta (pestaña Response) se ve el precio del producto, el nombre u otros campos necesarios en formato JSON.
- Haz clic en esta solicitud y cópiala como cURL (clic derecho → Copiar → Copiar como cURL) — esto te dará un conjunto completo de encabezados, cookies y parámetros.
- Verifica qué parámetros en la URL son obligatorios (código del producto, región, versión de la API), y cuáles se pueden eliminar sin perder datos.
Después de esto, solo necesitas repetir esta solicitud a través de una biblioteca HTTP normal, sustituyendo el código o ID del producto en lugar de renderizar toda la página completa. Esto funciona para la mayoría de los marketplaces — Wildberries, Ozon, Avito, así como para muchas plataformas extranjeras como Amazon y eBay.
Comparación de tráfico: HTML vs JSON API
La diferencia en el volumen de datos es tan grande que vale la pena mostrarla en cifras. A continuación, se presentan las mediciones promedio para una tarjeta de producto en los marketplaces populares.
| Método de scraping | Tamaño promedio de respuesta | Tiempo de carga | ¿Se necesita renderizado JS? |
|---|---|---|---|
| HTML completo a través de Selenium | 400-800 KB | 1.5-4 seg | Sí |
| Solicitud HTTP simple (requests) | 150-300 KB | 0.3-0.8 seg | No |
| API JSON oculto | 3-15 KB | 0.1-0.3 seg | No |
Al monitorear 50,000 productos al día, pasar de un navegador sin cabeza a solicitudes directas a la API reduce el tráfico de aproximadamente 30-40 GB a 300-700 MB al mes. Esto no solo representa un ahorro en el tráfico de proxies, sino también una reducción de la carga en la infraestructura del servidor del scraper — menos CPU para renderizar, menos memoria, más rápido en la recopilación de datos.
Ejemplo práctico en Python
Consideremos un ejemplo simplificado: obtener el precio y la disponibilidad de un producto a través de una solicitud directa al API interno en lugar de cargar la página completa. Este es un template educativo — los endpoints y parámetros exactos deben determinarse a través de DevTools para un sitio específico, ya que la estructura de las solicitudes puede variar según la región y la versión de la API.
import requests
def get_product_data(product_id: str, proxies: dict = None) -> dict:
"""
Obtiene datos del producto a través del API interno en lugar de HTML completo.
proxies — diccionario con proxies en formato requests: {"http": "...", "https": "..."}
"""
url = f"https://card.example-marketplace.ru/v2/detail"
params = {
"nm": product_id,
"dest": "-1257786", # región, se determina a través de DevTools
"spp": "0"
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0 Safari/537.36",
"Accept": "application/json",
"Referer": f"https://www.example-marketplace.ru/catalog/{product_id}/detail.aspx"
}
response = requests.get(
url,
params=params,
headers=headers,
proxies=proxies,
timeout=10
)
response.raise_for_status()
data = response.json()
product = data["products"][0]
return {
"id": product["id"],
"name": product["name"],
"price": product["salePriceU"] / 100,
"stock": product.get("totalQuantity", 0),
"rating": product.get("reviewRating", None)
}
if __name__ == "__main__":
proxy = {
"http": "http://user:pass@proxy-host:port",
"https": "http://user:pass@proxy-host:port"
}
result = get_product_data("123456789", proxies=proxy)
print(result)
Presta atención a tres puntos en este ejemplo. Primero, especificamos el encabezado Referer, porque muchas APIs verifican que la solicitud provenga "del navegador", y no directamente por URL. En segundo lugar, utilizamos un User-Agent realista, y no el predeterminado de la biblioteca requests, que es fácilmente detectable. En tercer lugar, toda la solicitud se realiza en una sola llamada HTTP sin renderizado — esto es lo que proporciona un ahorro significativo en tráfico y velocidad.
Para los endpoints de GraphQL, la lógica es similar, pero en lugar de parámetros GET, envías una solicitud POST con un cuerpo de solicitud en formato JSON, donde enumeras explícitamente los campos necesarios — esto reduce aún más el volumen de la respuesta, ya que el servidor devuelve solo los datos solicitados.
Trabajo con proxies en solicitudes a la API
Incluso al pasar a un formato JSON compacto, aún necesitas proxies — los marketplaces limitan el número de solicitudes desde una sola IP y bloquean en caso de actividad anómala. La elección correcta del tipo de proxy aquí influye directamente en la estabilidad del scraper.
Para el scraping masivo de APIs de marketplaces como Wildberries o Ozon, son adecuados los proxies de centros de datos — ofrecen alta velocidad y bajo costo de tráfico, lo cual es crítico en solicitudes frecuentes a endpoints JSON ligeros. Pero si un API específico está protegido por un anti-bot más estricto y bloquea subredes de centros de datos enteras, es más sensato cambiar a proxies residenciales — utilizan direcciones IP reales de usuarios domésticos y son menos propensos a ser bloqueados por subredes.
Para APIs que dependen de aplicaciones móviles (algunas versiones de endpoints de Avito o marketplaces devuelven datos solo a través de tráfico móvil), puede ser necesario conectarse a través de proxies móviles — imitan el tráfico de operadores de telefonía móvil reales y pasan las verificaciones que bloquean IPs normales.
Al configurar proxies en el scraper, también es importante espaciar las solicitudes en el tiempo y utilizar rotación de IP — incluso una solicitud JSON compacta, repetida 1000 veces por minuto desde una sola dirección, generará sospechas en el sistema de protección. Configura un pool de varias sesiones de proxies y distribuye la carga entre ellas, añadiendo retrasos aleatorios de 1 a 3 segundos entre solicitudes.
Puntos críticos: tokens, firmas, anti-bots
Los APIs ocultos no siempre están completamente abiertos. Algunos sitios protegen sus endpoints con mecanismos adicionales que deben tenerse en cuenta al construir el scraper.
- Tokens de sesión temporales — algunos APIs requieren una solicitud previa para obtener un token, que luego se pasa en el encabezado de las siguientes solicitudes y tiene un tiempo de vida limitado (generalmente de 5 a 30 minutos).
- Firma de solicitud (signature) — los parámetros de la solicitud se hash en el cliente con una clave secreta del código JS de la página. Esta firma debe ser reproducida manualmente, desglosando el algoritmo, o ejecutarse a través de un navegador sin cabeza solo en la etapa de obtención del token, y luego enviar solicitudes ligeras directamente.
- Limitación de tasa por IP y por User-Agent — al exceder la frecuencia de solicitudes, el sitio bloquea temporalmente el acceso. Esto se resuelve con rotación de proxies y retrasos razonables.
- Fingerprinting de encabezados — algunos sistemas verifican el conjunto completo de encabezados (orden, presencia de Accept-Language, Sec-Fetch-*) y bloquean solicitudes con un conjunto "incompleto", característico de scripts, no de navegadores.
- Dependencia geográfica de los datos — los precios y existencias en los marketplaces pueden variar según la región, por lo que es importante pasar el parámetro correcto de región/almacén en la solicitud, de lo contrario, los datos serán irrelevantes.
Si el API está cerrado con una firma de solicitud que es difícil de reproducir, una opción de compromiso es usar un navegador sin cabeza (Playwright, Puppeteer) solo para interceptar solicitudes de red y extraer la respuesta JSON lista, sin parsear el DOM. Esto es más lento que una solicitud HTTP directa, pero aún así más rápido y ligero que un scraping completo del diseño de la página.
Lista de verificación antes de lanzar el scraper en el API oculto
- Se encontró el endpoint a través de DevTools, se copió como cURL y se probó en Postman o a través de requests.
- Se determinaron los parámetros obligatorios de la solicitud (ID del producto, región, versión de la API) y se eliminaron los excesivos.
- Los encabezados User-Agent, Referer y Accept-Language se configuraron de manera realista.
- Se verificó si se requiere un token de sesión o firma de solicitud, y se pensó en la forma de obtenerlos.
- Se configuró la rotación de proxies y retrasos aleatorios entre solicitudes.
- Se eligió el tipo de proxy adecuado para la protección específica del sitio — centro de datos, residenciales o móviles.
- Se añadió el manejo de errores 429 y 403 con cambio automático a otro proxy.
- Se configuró el registro del volumen de tráfico para controlar el ahorro real.
Conclusión
Pasar del scraping de HTML completo al trabajo con un API oculto no es solo una optimización técnica, sino una reducción directa de los gastos en tráfico de proxies e infraestructura. En lugar de cargar cientos de kilobytes de marcado innecesario, obtienes un JSON compacto con exactamente los campos que necesitas para monitorear precios, existencias o calificaciones. Un beneficio adicional es la resistencia del scraper a los cambios en el diseño del sitio, ya que los APIs internos cambian con menos frecuencia que el frontend.
Sin embargo, la metodología para encontrar APIs no elimina la necesidad de proxies de calidad — los sistemas anti-bots de los marketplaces vigilan de cerca tanto las solicitudes HTML como las llamadas a los endpoints JSON. Si monitoreas Wildberries o Ozon en grandes volúmenes, comienza con rápidos proxies de centros de datos para reducir costos, y ante los primeros signos de bloqueos, cambia a pools de IP residenciales o móviles para un funcionamiento más estable del scraper.