Scrapear Temu en 2026 es un desafío técnico real. La plataforma no expone una API pública, sus precios cambian según geolocalización, y su stack anti-bot detecta IPs de datacenter en segundos. Si tu equipo de inteligencia de precios necesita scrapear Temu de forma fiable, tienes que elegir entre dos caminos: parsear HTML volátil o atacar los endpoints JSON internos. Esta guía cubre ambos, con código funcional y configuración de proxies residenciales a través de ProxyHat.
Por qué scrapear datos de productos y precios de Temu es distinto en 2026
Temu opera bajo Cloudflare Turnstile y un sistema de fingerprinting TLS/HTTP2 que clasifica conexiones antes incluso de servir HTML. No hay una API de datos de productos Temu documentada. Lo que existe es una capa interna de endpoints JSON —como /api/poppy/v1/search y /api/poppy/v1/goods/detail— que el frontend invoca para renderizar las tarjetas de productos. La decisión clave es: ¿parseas el HTML renderizado o llamas directamente a esos endpoints?
HTML renderizado vs. endpoints JSON internos
| Aspecto | Parsear HTML | Endpoints JSON internos |
|---|---|---|
| Estabilidad | Baja — clases CSS hasheadas cambian cada deploy | Media — esquema JSON más estable pero sin contrato |
| Datos disponibles | Lo que ve el usuario | Campos adicionales (sku, stock, shipping flags) |
| Velocidad | Lenta — descarga CSS, JS, imágenes | Rápida — ~200ms por request con proxy cercano |
| Riesgo de bloqueo | Alto — Cloudflare evalúa el render completo | Alto — requiere anti_content firmado |
| Mantenimiento | Fragilidad alta ante cambios de UI | Fragilidad media ante cambios de esquema |
La recomendación práctica: usa los endpoints JSON para volumen y consistencia, y reserva el HTML para validación cruzada o cuando necesites datos que solo aparecen en el render (como banners promocionales dinámicos).
El stack anti-bot de Temu: lo que te bloquea
Temu combina tres capas de protección que cualquier scraper de precios Temu debe superar:
- Cloudflare Turnstile + WAF: challenge JavaScript que evalúa el entorno del navegador. Si usas
requestsestándar, recibes un 403 antes de tocar el HTML. - Cabecera
anti_contentfirmada: un token generado client-side que valida la integridad de la petición. Sin él, los endpoints JSON devuelven{"success": false, "errorCode": 100}. Replicar este token requiere ingeniería inversa del JS de Temu, que cambia con frecuencia. - Fingerprinting TLS/HTTP2: Temu usa JA3/JA4 fingerprinting para distinguir navegadores reales de librerías HTTP.
requestsyhttpxtienen huellas conocidas que se bloquean automáticamente.
Las IPs de datacenter son la primera línea de filtrado. Cloudflare marca rangos ASN conocidos (AWS, DigitalOcean, Hetzner) con un score de reputación bajo, y Temu las rechaza antes de llegar al challenge. Por eso los proxies residenciales con geo-targeting no son opcionales: son el requisito mínimo para entrar.
Dónde están los datos: selectores, atributos y endpoints
El blob de estado embebido
Las páginas de producto y listing de Temu incluyen un bloque <script id="__NEXT_DATA__" type="application/json"> (o un equivalente serializado) que contiene el estado inicial del render. Es la fuente más rica de datos sin necesidad de llamar a la API:
// XPath al blob de estado
//xpath: //script[@id="__NEXT_DATA__"]
// Selectores CSS para tarjetas de producto en el listing
// Clases hasheadas — cambian entre deploys, usa data-uniqid
div[data-uniqid] > div[class*="productCard"]
// Precio dentro de la tarjeta
span[class*="priceText"]
// Título
a[class*="goodsTitle"]
// Imagen
img[class*="goodsImage"]
El atributo data-uniqid es más estable que las clases CSS hasheadas (tipo _3kQ2xL), que cambian en cada release. Construye tus selectores sobre data-uniqid y estructura semántica whenever possible.
Endpoints JSON internos
Los dos endpoints principales que el frontend de Temu invoca:
# Búsqueda / listing de productos
POST https://www.temu.com/api/poppy/v1/search
Content-Type: application/json
# Detalle de producto
GET https://www.temu.com/api/poppy/v1/goods/detail?goodsId={goods_id}
# Parámetros clave de search:
# {"keyword": "laptop", "page": 1, "pageSize": 50,
# "sortType": 0, "anti_content": "..."}
El campo anti_content es obligatorio. Sin un token válido, la respuesta es un error. Algunos equipos extraen este token interceptando el JS con Playwright o Puppeteer, lo reutilizan durante su ventana de validez (típicamente 5–10 minutos), y luego lo rotan. Otros optan por renderizar la página completa con un navegador headless y extraer el __NEXT_DATA__.
Rate limits y por qué los proxies residenciales son obligatorios
Temu no documenta rate limits públicos, pero pruebas empíricas muestran los siguientes umbrales:
- ~30 requests/min desde una sola IP antes de recibir challenges de Cloudflare.
- ~100 requests/min desde una IP residencial con headers realistas antes de soft-block (403 temporal).
- ~1500 requests/min distribuidos entre 50+ IPs residenciales con rotación es sostenible para monitoring de catálogo.
El motivo por el que necesitas proxies residenciales con geo-targeting a nivel ciudad no es solo evasión: los precios y el shipping de Temu varían por región. Un producto puede costar $9.99 en California y $12.49 en Nueva York, con diferentes opciones de envío. Si tu scraper de precios Temu usa una IP aleatoria, obtendrás datos inconsistentes.
Con ProxyHat, puedes fijar el país e incluso la ciudad en el nombre de usuario:
# IP residencial en EE.UU.
http://user-country-US:pass@gate.proxyhat.com:8080
# IP residencial en Berlín, Alemania
http://user-country-DE-city-berlin:pass@gate.proxyhat.com:8080
# SOCKS5 con geo-targeting
socks5://user-country-US-city-newyork:pass@gate.proxyhat.com:1080
Para monitoring de precios en múltiples mercados, ejecuta workers paralelos con diferentes -country- y compara resultados. Consulta nuestra página de precios para estimar costes por región.
Ejemplo práctico: scrapear Temu con curl_cffi y ProxyHat
La librería curl_cffi impersona el fingerprint TLS de navegadores reales (Chrome, Firefox, Safari), lo que permite pasar el filtro JA3/JA4 de Cloudflare. Combinada con proxies residenciales de ProxyHat, es la stack más eficiente para extraer datos de Temu sin navegador headless.
from curl_cffi import requests as cffi_requests
import json
# Configuración del proxy residencial ProxyHat
PROXY = "http://user-country-US:pass@gate.proxyhat.com:8080"
# Headers realistas
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/124.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
"Referer": "https://www.temu.com/",
}
# 1) Fetch de la página de producto (extrae __NEXT_DATA__)
url = "https://www.temu.com/goods-p-123456789.html"
resp = cffi_requests.get(
url,
headers=headers,
proxies={"http": PROXY, "https": PROXY},
impersonate="chrome124",
timeout=15,
)
# 2) Extraer el blob __NEXT_DATA__
import re
match = re.search(
r'<script id="__NEXT_DATA__"[^>]*>(.*?)</script>',
resp.text,
re.DOTALL
)
if match:
data = json.loads(match.group(1))
# Navegar al estado del producto
goods = data["props"]["pageProps"]["goods"]
print(json.dumps({
"goods_id": goods.get("goodsId"),
"title": goods.get("goodsName"),
"price": goods.get("minNormalPrice"), # en centavos
"skus": [
{"sku_id": s.get("skuId"),
"price": s.get("price"),
"stock": s.get("stock")}
for s in goods.get("skuList", [])[:3]
]
}, indent=2, ensure_ascii=False))
Respuesta truncada de ejemplo:
{
"goods_id": 123456789,
"title": "Wireless Bluetooth Earbuds Pro",
"price": 899, // $8.99 en centavos
"skus": [
{"sku_id": 987654, "price": 899, "stock": 1200},
{"sku_id": 987655, "price": 1099, "stock": 340},
{"sku_id": 987656, "price": 1299, "stock": 0}
]
}
Nota: Los precios en Temu vienen en centavos. Divide entre 100 para obtener dólares. El campo
minNormalPricepuede no existir en todas las páginas — algunos productos usanminGroupPricepara ofertas con descuento.
Sesiones sticky, reintentos y paginación
Sesiones sticky para consistencia de carrito y shipping
Cuando necesitas simular un flujo de usuario completo (buscar → ver producto → verificar shipping), mantener la misma IP es crítico. Si la IP cambia a mitad del flujo, Temu puede mostrar precios o tarifas de envío diferentes. Usa el flag -session- en ProxyHat:
# Sesión sticky con IP residencial en EE.UU.
# La misma IP se mantiene durante toda la sesión
SESSION_PROXY = (
"http://user-country-US-session-abc123:pass"
"@gate.proxyhat.com:8080"
)
# Reutiliza SESSION_PROXY en todas las requests del flujo
# Cambia "abc123" para iniciar una nueva sesión con nueva IP
Reintentos con backoff exponencial
import time
import random
def fetch_with_retry(url, max_retries=5, **kwargs):
for attempt in range(max_retries):
try:
resp = cffi_requests.get(url, **kwargs)
if resp.status_code == 200:
return resp
elif resp.status_code == 403:
# Soft-block: rotar IP cambiando sesión
kwargs["proxies"] = {
"http": f"http://user-country-US-"
f"session-retry{attempt}:pass@gate.proxyhat.com:8080",
"https": f"http://user-country-US-"
f"session-retry{attempt}:pass@gate.proxyhat.com:8080",
}
time.sleep(2 ** attempt + random.uniform(0, 1))
else:
time.sleep(2 ** attempt)
except Exception as e:
time.sleep(2 ** attempt)
return None
Paginación del listing
def scrape_listing(keyword, max_pages=10):
results = []
for page in range(1, max_pages + 1):
# Rotar sesión por página para distribuir requests
proxy = (
f"http://user-country-US-session-"
f"pg{page}:pass@gate.proxyhat.com:8080"
)
url = f"https://www.temu.com/search_result.html?search_key={keyword}&page={page}"
resp = fetch_with_retry(
url,
headers=headers,
proxies={"http": proxy, "https": proxy},
impersonate="chrome124",
timeout=15,
)
if resp is None:
print(f"Página {page} falló tras reintentos")
break
# Extraer productos del __NEXT_DATA__
match = re.search(
r'<script id="__NEXT_DATA__"[^>]*>(.*?)</script>',
resp.text, re.DOTALL
)
if match:
data = json.loads(match.group(1))
items = data.get("props", {}).get("pageProps", {}).get("searchResult", [])
results.extend(items)
print(f"Página {page}: {len(items)} productos")
time.sleep(random.uniform(2, 5)) # Rate limiting cortés
return results
Para casos de uso más amplios de web scraping, revisa nuestra guía de casos de uso de web scraping y la de SERP tracking.
Ética, TOS y consideraciones legales
Scrapear Temu —o cualquier plataforma e-commerce— opera en una zona legal gris que depende de jurisdicción y uso. Considera lo siguiente:
- Datos públicos del catálogo únicamente: extraer precios, títulos, imágenes y disponibilidad de productos visibles sin login es generalmente aceptable. Scrapear datos de cuenta, carritos, o información personal de usuarios no lo es.
- CFAA (EE.UU.): la Computer Fraud and Abuse Act se ha interpretado para proteger acceso no autorizado a sistemas. Extraer datos públicamente accesibles sin evadir barreras técnicas tiene precedente favorable (hiQ Labs vs. LinkedIn), pero evadir CAPTCHAs o sistemas anti-bot puede ser interpretado como "acceso no autorizado".
- GDPR (UE): si los datos scrapeados contienen información personal (reviews con nombres de usuarios, por ejemplo), el procesamiento está sujeto al GDPR. Limita tu scraper a datos de producto no personales.
- Términos de servicio de Temu: los TOS probablemente prohíben scraping automatizado. Violar TOS no es necesariamente ilegal, pero puede resultar en bans de IP y acciones civiles. Lee los TOS antes de desplegar en producción.
- Feed oficial de merchant: si eres vendedor o partner de Temu, el Merchant Feed API es la ruta legítima para acceder a datos de catálogo. Úsala cuando esté disponible — es más fiable, legalmente segura, y no requiere proxies.
La documentación técnica de ProxyHat está disponible en docs.proxyhat.com para configuración avanzada de proxies.
Errores comunes y casos límite
- Usar
requestssin impersonación TLS: Cloudflare detecta la huella JA3 de Python requests en <1s. Usacurl_cfficonimpersonate="chrome124"o similar. - No rotar
anti_content: el token tiene una validez limitada. Si lo reutilizas durante horas, los endpoints JSON empiezan a devolver errores silenciosos (datos vacíos, no 403). - Ignorar la variación de precios por geo: si comparas precios de competidores sin fijar la región del proxy, tus datos serán inconsistentes. Fija
-country-US(o el mercado que monitorices) en todos los workers. - Scrapear sin
RefereryAccept-Language: Temu valida coherencia de headers. UnAccept-Language: zh-CNcon IP de EE.UU. es una señal de bot. - Concurrencia excesiva por IP: más de 30 requests/min desde una IP residencial dispara challenges. Distribuye con rotación.
Puntos clave
- Endpoints JSON > HTML: usa
/api/poppy/v1/searchygoods/detailpara volumen; reserva HTML para validación.- curl_cffi + ProxyHat residencial: impersonación TLS + IP residencial con geo es la combinación que funciona.
- Geo-targeting obligatorio: precios y shipping varían por región. Fija
-country-USo el mercado objetivo.- Sesiones sticky para flujos: usa
-session-cuando necesites consistencia entre búsquedas, productos y shipping.- Rate limit ~30 req/min por IP: distribuye con rotación; 1500 req/min es sostenible con 50+ IPs.
- Ética primero: datos públicos de catálogo únicamente, sin cuentas ni datos personales. Considera el Merchant Feed API si eres partner.
Preguntas frecuentes
¿Qué es scrapear datos de productos y precios de Temu?
Es la extracción automatizada de información del catálogo público de Temu —títulos, precios, SKUs, disponibilidad, imágenes— usando scripts que simulan navegación web. Como Temu no ofrece una API pública, se recurre a parsing de HTML o a los endpoints JSON internos que el frontend invoca, combinados con proxies residenciales para evitar bloqueos anti-bot.
¿Por qué importa para usuarios de proxies?
Temu usa Cloudflare Turnstile, fingerprinting TLS/HTTP2 y un token anti_content firmado que bloquea IPs de datacenter automáticamente. Sin proxies residenciales con geo-targeting, no es posible acceder al catálogo de forma fiable. Además, los precios varían por región, así que el proxy debe estar geolocalizado para obtener datos consistentes.
¿Qué tipo de proxy funciona mejor para scrapear Temu?
Proxies residenciales con geo-targeting a nivel país o ciudad. Las IPs de datacenter son detectadas por Cloudflare en segundos. Los proxies móviles también funcionan pero son más caros. La configuración ideal en ProxyHat es user-country-US:pass@gate.proxyhat.com:8080 para EE.UU., ajustando el país según el mercado que monitorices.
¿Cómo evitas bloqueos al scrapear Temu?
Usa curl_cffi con impersonación TLS de Chrome, proxies residenciales con rotación, headers realistas (User-Agent, Referer, Accept-Language coherentes con la geo del proxy), rate limiting de máximo 30 requests/min por IP, sesiones sticky para flujos multi-página, y backoff exponencial en reintentos. Extrae el token anti_content con un navegador headless si atacas los endpoints JSON directamente.
¿Es legal scrapear Temu?
Extraer datos públicamente accesibles del catálogo (sin login) es generalmente legal bajo precedentes como hiQ vs. LinkedIn en EE.UU. Sin embargo, evadir sistemas anti-bot puede interpretarse como acceso no autorizado bajo la CFAA, y los TOS de Temu probablemente prohíben scraping. Si eres partner o vendedor, el Merchant Feed API es la ruta legalmente segura. Consulta con asesoría legal antes de desplegar en producción.






