Скрейпинг Temu в 2026: API против HTML
Temu — один из крупнейших e-commerce маркетплейсов мира, запущенный PDD Holdings в 2022 году и к 2024 году достигший более 50 миллиардов долларов валового объёма товаров (GMV) (Reuters, 2025). Для команд ценовой разведки и e-commerce аналитики скрейпинг Temu стал критически важной задачей. Однако у Temu нет публичного API для доступа к каталогу товаров, поэтому разработчикам приходится выбирать между парсингом нестабильного HTML и обращением к внутренним JSON-эндпоинтам.
Понимание того, как скрейпить данные товаров и цен Temu в 2026 году, требует знания антибот-стека платформы, правильного использования прокси и умения находить скрытые данные в ответах сервера. В этом руководстве мы разберём практическую реализацию Temu price scraper — от обхода Cloudflare до парсинга JSON через /api/poppy/v1/search и эндпоинты деталей товаров.
Два пути получения данных
Когда вы открываете страницу поиска или карточку товара на Temu, браузер выполняет десятки запросов. Большинство из них — это внутренние JSON-API, которые возвращают структурированные данные о товарах, ценах, SKU, вариантах доставки и отзывах. Вот основные эндпоинты:
/api/poppy/v1/search— поиск по каталогу, возвращает список товаров с ценами, изображениями и базовыми атрибутами./api/poppy/v1/goods/detail— детальная информация о товаре: полный SKU-лист, спецификации, цена со скидкой, варианты доставки./api/poppy/v1/review/list— отзывы покупателей с рейтингами.
Парсинг HTML-карточек товаров (div[data-uniqid], хешированные CSS-классы вида _2BEOSv) — это более простой подход, но он хрупок: классы меняются при каждом деплое, а вёрстка оптимизируется для мобильных устройств. Обращение к JSON-эндпоинтам даёт структурированные данные, но требует обхода антибот-защиты и подписи запросов.
Ключевой вывод: если вам нужен Temu product data API для ценового мониторинга, JSON-эндпоинты — единственный надёжный источник. HTML-парсинг подходит только для разовых выгрузок или проверки наличия товаров.
Антибот-стек Temu: что вас ждёт
Temu использует многоуровневую систему защиты от автоматизированного доступа. Понимание каждого слоя необходимо для построения стабильного скрейпера.
Cloudflare Turnstile и JS-челленджи
Temu защищён Cloudflare Turnstile — системой проверки, которая анализирует поведение пользователя, отпечатки браузера и TLS-параметры. В отличие от классической CAPTCHA, Turnstile часто работает незаметно, но при подозрительной активности выдаёт интерактивный челлендж. Datacenter-IP-адреса помечаются практически мгновенно: Cloudflare поддерживает базу ASN, и запросы с известных дата-центров (AWS, Google Cloud, DigitalOcean) получают повышенный риск-скор.
Подписанный заголовок anti_content
Каждый запрос к /api/poppy/v1/ требует заголовка anti_content — сгенерированного на стороне клиента токена, содержащего зашифрованную информацию о сессии, отпечатке браузера и временной метке. Алгоритм генерации регулярно обновляется и обфусцирован. Без валидного anti_content сервер возвращает ошибку {"err_code": 403, "err_msg": "verification failed"}.
На практике у вас есть два варианта:
- Реверс-инжиниринг алгоритма генерации — сложный и хрупкий путь, требующий постоянного обновления при каждом изменении клиентского кода Temu.
- Использование браузерного движка (Playwright, Puppeteer) для автоматической генерации токена — более надёжный, но ресурсоёмкий подход.
TLS/HTTP2-фингерпринтинг
Даже с валидным anti_content и residential-прокси, запрос может быть отклонён из-за несоответствия TLS-отпечатка. Обычные HTTP-библиотеки Python (requests, httpx) используют TLS-библиотеки, чьи отпечатки (JA3/JA4) отличаются от реальных браузеров. Решение — библиотека curl_cffi, которая эмулирует TLS-отпечатки Chrome, Firefox и Safari на уровне C-библиотеки curl.
Поиск данных: __NEXT_DATA__ и JSON-эндпоинты
Помимо прямых API-вызовов, Temu встраивает большой блок данных в HTML-страницы в виде тега <script id="__NEXT_DATA__" type="application/json"> (или аналогичного паттерна, зависящего от версии фронтенда). Этот блок содержит сериализованное состояние приложения: результаты поиска, информацию о товаре, цены и SKU.
Структура данных товара
Вот как выглядит типичный (усечённый) ответ от эндпоинта деталей товара:
{
"data": {
"goods_id": "501299873456",
"goods_name": "Wireless Bluetooth Earbuds Pro",
"cat_id": 1518,
"image": {
"img_url": "https://img.kwcdn.com/product/..."
},
"skus": [
{
"sku_id": "sku_8821001",
"sku_price": {
"price": 1299,
"price_info": {"amount": 12.99, "currency": "USD"}
},
"sku_attr": {"color": "Black", "size": "Standard"}
},
{
"sku_id": "sku_8821002",
"sku_price": {
"price": 1499,
"price_info": {"amount": 14.99, "currency": "USD"}
},
"sku_attr": {"color": "White", "size": "Standard"}
}
],
"shipping_info": {
"free_shipping": true,
"estimated_delivery": "5-8 days"
}
},
"err_code": 0,
"err_msg": ""
}
Цены в API представлены в центах (поле price) с дополнительным полем amount в долларах. SKU-лист содержит все варианты товара с индивидуальными ценами — это критически важно для ценового мониторинга, так как разные варианты могут иметь разную цену.
Хешированные CSS-классы и data-uniqid
Если вы всё же парсите HTML, обратите внимание на атрибут data-uniqid на карточках товаров — он содержит уникальный идентификатор, соответствующий goods_id. CSS-классы вида _2BEOSv, _3rH5kN генерируются автоматически и меняются при каждом деплое, поэтому XPath-селекторы вроде //div[contains(@class, "goods-name")] более устойчивы, чем полные имена классов.
Rate-limit и почему residential-прокси обязательны
Temu не публикует официальные лимиты на запросы, но на основе практического тестирования можно выделить следующие пороги:
| Тип запроса | Примерный лимит (на IP) | Реакция при превышении |
|---|---|---|
| Поиск (/api/poppy/v1/search) | ~30–50 запросов / минуту | Captcha-челлендж, затем 403 |
| Детали товара (/goods/detail) | ~60–80 запросов / минуту | Soft-block на 5–15 минут |
| HTML-страницы | ~20–30 запросов / минуту | Cloudflare challenge page |
Эти цифры — приблизительные и зависят от множества факторов: времени суток, нагрузки на серверы, репутации IP-адреса. Datacenter-IP-адреса блокируются значительно быстрее — часто после 3–5 запросов.
Геозависимость цен и доставки
Цены на Temu, стоимость доставки и доступность товаров варьируются в зависимости от региона. Один и тот же товар может стоить $12.99 в США и €14.50 в Германии, с разной оценкой сроков доставки. Это означает, что для корректного ценового мониторинга необходимо использовать residential-прокси с геотаргетингом на уровне страны и города.
С ProxyHat вы можете указать страну и город прямо в имени пользователя прокси:
# США, Нью-Йорк
http://user-country-US-city-newyork:pass@gate.proxyhat.com:8080
# Германия, Берлин
http://user-country-DE-city-berlin:pass@gate.proxyhat.com:8080
# Великобритания, Лондон
http://user-country-GB-city-london:pass@gate.proxyhat.com:8080
Подробнее о доступных локациях — на странице локаций ProxyHat.
Практический пример: Python + curl_cffi + ProxyHat
Ниже — рабочий пример скрейпера Temu, использующего curl_cffi для эмуляции TLS-отпечатка Chrome и residential-прокси ProxyHat для обхода Cloudflare.
from curl_cffi import requests as cffi_requests
import json
# ProxyHat residential proxy с геотаргетингом на США
proxy_url = "http://user-country-US:PASSWORD@gate.proxyhat.com:8080"
proxies = {"http": proxy_url, "https": proxy_url}
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": "application/json, text/plain, */*",
"Accept-Language": "en-US,en;q=0.9",
"Referer": "https://www.temu.com/",
"Origin": "https://www.temu.com",
}
# Шаг 1: Получаем страницу поиска через браузерную сессию
session = cffi_requests.Session(impersonate="chrome124")
# Шаг 2: Запрос к внутреннему JSON-API поиска
search_url = "https://www.temu.com/api/poppy/v1/search"
params = {
"search_key": "wireless earbuds",
"page": 1,
"page_size": 20,
"search_method": "search",
}
response = session.get(
search_url,
params=params,
headers=headers,
proxies=proxies,
timeout=15,
)
data = response.json()
# Шаг 3: Извлекаем данные товаров
if data.get("err_code") == 0:
items = data.get("data", {}).get("items", [])
for item in items[:3]:
goods_id = item.get("goods_id")
title = item.get("goods_name")
price_cents = item.get("min_normal_price", {}).get("price", 0)
price_usd = price_cents / 100
print(f"{goods_id} | {title} | ${price_usd:.2f}")
else:
print(f"Error: {data.get('err_code')} - {data.get('err_msg')}")
Этот код использует impersonate="chrome124", что заставляет curl_cffi отправлять запросы с TLS-отпечатком, идентичным Chrome 124. Residential-прокси ProxyHat обеспечивает реальный IP-адрес из США, что снижает риск срабатывания Cloudflare.
Получение деталей товара
# Запрос деталей товара по goods_id
detail_url = "https://www.temu.com/api/poppy/v1/goods/detail"
params = {
"goods_id": "501299873456",
"goods_id_list": "[501299873456]",
}
detail_response = session.get(
detail_url,
params=params,
headers=headers,
proxies=proxies,
timeout=15,
)
detail_data = detail_response.json()
if detail_data.get("err_code") == 0:
goods = detail_data.get("data", {})
skus = goods.get("skus", [])
print(f"Goods: {goods.get('goods_name')}")
print(f"SKU count: {len(skus)}")
for sku in skus:
sku_id = sku.get("sku_id")
amount = sku.get("sku_price", {}).get("price_info", {}).get("amount")
attrs = sku.get("sku_attr", {})
print(f" {sku_id} | ${amount} | {attrs}")
Альтернатива: парсинг __NEXT_DATA__ из HTML
Если JSON-эндпоинты недоступны из-за ужесточения антибот-проверок, можно извлечь данные из встроенного блока __NEXT_DATA__:
from bs4 import BeautifulSoup
import json
# Загружаем HTML-страницу товара
html_response = session.get(
"https://www.temu.com/goods-501299873456.html",
headers=headers,
proxies=proxies,
timeout=15,
)
soup = BeautifulSoup(html_response.text, "html.parser")
next_data_script = soup.find("script", id="__NEXT_DATA__")
if next_data_script:
next_data = json.loads(next_data_script.string)
# Навигация по структуре зависит от версии фронтенда
goods_data = next_data.get("props", {}).get("pageProps", {}).get("goods", {})
print(f"Goods ID: {goods_data.get('goods_id')}")
print(f"Name: {goods_data.get('goods_name')}")
skus = goods_data.get("skus", [])
print(f"SKU count: {len(skus)}")
Sticky-сессии, повторы и пагинация
Для скрейпинга Temu критически важно использовать sticky-сессии — прокси, которые сохраняют один и тот же IP-адрес на протяжении серии запросов. Это необходимо по двум причинам:
- Корзина и доставка: при добавлении товаров в корзину и расчёте стоимости доставки Temu привязывает сессию к IP. Смена IP между запросами приводит к пустой корзине и некорректным ценам доставки.
- Пагинация: при постраничном обходе результатов поиска смена IP может привести к разным результатам, так как Temu персонализирует выдачу.
В ProxyHat sticky-сессии включаются через флаг -session- в имени пользователя:
# Sticky-сессия с идентификатором "temu-search-1"
http://user-country-US-session-temu-search-1:pass@gate.proxyhat.com:8080
Используйте уникальный идентификатор сессии для каждого параллельного потока скрейпинга. Сессия удерживает IP-адрес в течение примерно 10–30 минут, после чего автоматически ротируется.
Стратегия пагинации с ротацией
import time
import random
def scrape_search_pages(query, max_pages=10):
results = []
for page in range(1, max_pages + 1):
# Новая sticky-сессия для каждой страницы
session_id = f"temu-{query.replace(' ', '-')}-p{page}"
proxy = f"http://user-country-US-session-{session_id}:pass@gate.proxyhat.com:8080"
proxies = {"http": proxy, "https": proxy}
try:
response = session.get(
"https://www.temu.com/api/poppy/v1/search",
params={"search_key": query, "page": page, "page_size": 20},
headers=headers,
proxies=proxies,
timeout=15,
)
data = response.json()
if data.get("err_code") != 0:
print(f"Page {page}: error {data.get('err_code')}")
# Повтор с новой сессией
time.sleep(random.uniform(3, 7))
continue
items = data.get("data", {}).get("items", [])
if not items:
break
results.extend(items)
print(f"Page {page}: {len(items)} items")
# Случайная задержка между запросами
time.sleep(random.uniform(2, 5))
except Exception as e:
print(f"Page {page}: {e}")
time.sleep(random.uniform(5, 10))
return results
Стратегия повторов
При получении 403 или captcha-челленджа:
- Не повторяйте сразу — это усугубит блокировку. Подождите 30–60 секунд.
- Смените сессию — используйте новый
-session-идентификатор для получения нового IP. - Смените гео — если блокировка persists, попробуйте другой город или штат.
- Уменьшите частоту — снизьте количество запросов в минуту до 15–20.
Этика, TOS и правовые аспекты
Скрейпинг публичных данных каталога Temu (названия товаров, цены, изображения, спецификации) обычно считается допустимым, поскольку эти данные общедоступны и не защищены аутентификацией. Однако есть важные ограничения:
Что можно скрейпить
- Публичный каталог товаров: названия, цены, описания, изображения.
- Отзывы и рейтинги, видимые без входа в аккаунт.
- Категории и навигационную структуру.
Чего следует избегать
- Скрейпинг данных аккаунтов — личная информация покупателей, заказы, адреса доставки. Это нарушает GDPR в ЕС и CCPA в Калифорнии.
- Обход аутентификации — доступ к закрытым разделам через подделку токенов.
- Скрейпинг с высокой нагрузкой — намеренное перегружение серверов (DoS-подобное поведение) может подпадать под Computer Fraud and Abuse Act (CFAA) в США.
- Нарушение robots.txt — всегда проверяйте
https://www.temu.com/robots.txtперед началом скрейпинга.
Когда предпочесть официальный merchant feed
Если вы — продавец на Temu или партнёр, у вас есть доступ к Temu Merchant API (через Seller Center). Этот API предоставляет структурированный доступ к данным о ваших товарах, заказах и аналитике без необходимости скрейпинга. Для ценового мониторинга конкурентов скрейпинг остаётся единственным вариантом, но для управления собственным каталогом всегда используйте официальный API.
Для более широкого контекста использования прокси в e-commerce скрейпинге, см. наш материал о применении прокси для веб-скрейпинга и SERP-трекинге. Ценовую информацию о прокси-планах ProxyHat можно найти на странице тарифов. Документация по подключению доступна на docs.proxyhat.com.
Ключевые выводы
- JSON-эндпоинты предпочтительнее HTML:
/api/poppy/v1/searchи/goods/detailдают структурированные данные, устойчивые к изменениям вёрстки. - Residential-прокси обязательны: datacenter-IP блокируются Cloudflare за 3–5 запросов. Используйте геотаргетинг
-country-USдля корректных цен и доставки. - TLS-фингерпринтинг — реальная угроза: используйте
curl_cffiсimpersonate="chrome124"для эмуляции браузерного TLS-отпечатка. - Sticky-сессии для консистентности: флаг
-session-сохраняет IP для пагинации и расчёта доставки. - Соблюдайте этику: скрейпите только публичный каталог, не трогайте аккаунты и личные данные, проверяйте
robots.txt. - Цены в API — в центах: поле
priceсодержит значение в центах,amount— в долларах/евро.
FAQ
Можно ли скрейпить Temu без прокси?
Технически — да, но практически вы получите блокировку после 3–5 запросов с datacenter-IP или после 20–30 запросов с домашнего IP. Cloudflare Turnstile и TLS-фингерпринтинг Temu эффективно обнаруживают автоматизированные запросы. Residential-прокси с геотаргетингом — это не опция, а необходимость для любого серьёзного скрейпинга Temu. Без прокси вы рискуете не только блокировкой IP, но и постоянным попаданием в captcha-челленджи, которые делают скрейпинг экономически нецелесообразным.
Какой тип прокси лучше для скрейпинга Temu?
Residential-прокси — оптимальный выбор для Temu. Они используют реальные IP-адреса домашних интернет-провайдеров, что делает их неотличимыми от обычных пользователей. Mobile-прокси также работают, но они дороже и медленнее. Datacenter-прокси категорически не подходят — Cloudflare помечает их практически мгновенно. ProxyHat предоставляет residential-прокси с геотаргетингом на уровне страны и города, что критически важно для Temu, так как цены и стоимость доставки зависят от региона покупателя.
Как обойти заголовок anti_content в API Temu?
Заголовок anti_content — это подписанный токен, генерируемый клиентским JavaScript Temu. Реверс-инжиниринг алгоритма возможен, но требует постоянного обновления при каждом изменении фронтенда. Более практичный подход — использование браузерного движка (Playwright или Puppeteer) для автоматической генерации токена. Альтернативно, можно извлекать данные из встроенного блока __NEXT_DATA__ в HTML, который не требует отдельного API-вызова и содержит большую часть тех же данных.
Как часто меняются цены на Temu?
Цены на Temu могут меняться несколько раз в день, особенно во время промо-акций и распродаж. Практический опыт показывает, что для ценового мониторинга достаточно обновлять данные каждые 6–12 часов. При скрейпинге большого каталога (10 000+ товаров) рекомендуется распределить запросы во времени, чтобы не превышать 30–40 запросов в минуту на один IP-адрес. Использование sticky-сессий с ротацией каждые 50–100 запросов обеспечивает баланс между стабильностью и обходом лимитов.
Законно ли скрейпить данные товаров Temu?
Скрейпинг публично доступных данных каталога (цены, названия, описания товаров) в большинстве юрисдикций считается законным, так как эти данные не защищены аутентификацией и не являются конфиденциальными. Однако необходимо соблюдать условия обслуживания (TOS) Temu, не перегружать серверы и не собирать личные данные пользователей. В США дело hiQ Labs v. LinkedIn (2022) подтвердило, что скрейпинг публичных данных не нарушает CFAA. В ЕС необходимо учитывать GDPR при обработке любых персональных данных.






