Если вам нужны данные о товарах TikTok Shop для исследования цен или ассортимента, начинать стоит с официальных путей. TikTok Shop Partner API отдаёт полный каталог и данные заказов, но только по магазинам, которые авторизовали ваше приложение. TikTok Research API возвращает поля товара, цены и числа продаж для магазинов ЕС, но только одобренным некоммерческим исследователям. Большинство коммерческих команд, изучающих конкурентов, в итоге берут лицензированные данные у аналитических сервисов или используют медленный и аккуратный сборщик, который читает структурированные данные, уже опубликованные на публичных страницах товаров, через IP в исследуемом рынке.
Это руководство написано для маркетинговых исследований. Оно не связано с TikTok и не одобрено им, а приватные подписанные внутренние API TikTok в нём не рассматриваются.
Какие данные о товарах TikTok Shop на самом деле нужны командам
Большинство исследовательских вопросов сводится примерно к восьми полям: название товара, текущая цена, базовая цена (а значит, и скидка), число продаж, магазин, рейтинг и количество отзывов, категория и то, какие авторы продвигают товар.
- Исследование цен. Текущая цена, базовая цена, валюта и действующие акции в сравнении между продавцами одного и того же или аналогичного товара. Нужны согласованные метки времени и фиксированный рынок. Цена с британской витрины и цена с немецкой — это два разных наблюдения, а не одно зашумлённое.
- Анализ ассортимента. Какие категории охватывает магазин, сколько у него SKU и вариантов и где его цены находятся внутри категории. Обычно достаточно еженедельных снимков.
- Выявление трендов. Изменения числа продаж и количества отзывов во времени по категориям. Абсолютные значения важны меньше, чем наклон, и это удачно, потому что отображаемые цифры продаж неточны (подробнее ниже).
- Картирование авторов и партнёров. Какие авторы ссылаются на товар. С юридической точки зрения это самое чувствительное поле, потому что речь о людях, а не о товарах.
Если вы уже строили трекеры цен для других маркетплейсов, схема знакомая. Наши руководства по автоматическому мониторингу цен конкурентов и отслеживанию цен на разных рынках описывают сам пайплайн. На TikTok Shop отличается то, какая часть каталога закрыта привязкой к рынку и логином.
Официальные пути к данным TikTok Shop
Есть три легитимных источника структурированных данных TikTok Shop, и ни один из них не отдаёт коммерческой команде каталоги конкурентов просто так. Всё равно проверьте их первыми: первые два бесплатны, если вы подходите под условия, а третий часто обходится дешевле собственной разработки.
TikTok Shop Partner Center и TTS API
TikTok Shop Partner Center — место, где разработчики регистрируют приложения для TikTok Shop Open Platform. Собственный обзор TikTok описывает TTS API как доступ к «authorized TikTok Shop data, including catalogs, orders, shipments, payments, and more» («авторизованным данным TikTok Shop, включая каталоги, заказы, отправки, платежи и другое»). Среди категорий — Product, Order, Fulfillment, Return & Refund, Logistics, Promotion, Finance, Seller, Authorization, Events, Data Reconciliation и Supply Chain API.
Ключевое слово здесь — авторизованным. В документации перечислены три типа авторизации: продавец (магазин даёт вашему приложению доступ), автор и партнёр. Каждый из них требует согласия владельца данных. Если вы продавец или разработчик инструмента, чьи клиенты — продавцы, это лучшие данные, какие можно получить: точные цены, реальные остатки и реальное число заказов по этим магазинам. Но посмотреть на магазины, которые не подключили ваше приложение, так нельзя. В документации также перечислены поддерживаемые регионы и локали с пометкой, что доступность меняется по мере открытия рынков.
TikTok Research API, в котором есть данные магазинов ЕС
TikTok Research API известен в основном публичными видео, комментариями и аккаунтами. Но в нём есть и три эндпоинта TikTok Shop, которые многие упускают. Эндпоинт shop info возвращает рейтинг магазина, количество отзывов, число проданных товаров и показатель эффективности. Эндпоинт shop products возвращает название товара, цену, описание, число продаж, количество отзывов и распределение оценок от 1 до 5 звёзд. Эндпоинт product reviews возвращает текст отзыва, оценку и метки времени. Все три ограничены магазинами и товарами, доступными в ЕС, и возвращают не более 10 результатов за вызов.
Подвох — в требованиях к участникам. Доступ получают академические учреждения из США, ЕЭЗ, Великобритании, Канады и Швейцарии, некоммерческие исследовательские организации в ЕС и некоторые бразильские учреждения, изучающие безопасность молодёжи. Заявители должны быть «independent of commercial interests» («независимы от коммерческих интересов»). FAQ по Research API указывает стандартную квоту в 1000 запросов в день. Университетской группе, изучающей социальную коммерцию в ЕС, стоит подать заявку; ценовая команда бренда под условия не подходит и не должна пользоваться чужим исследовательским доступом.
Лицензированные данные от аналитических сервисов
Существует целая категория аналитических продуктов для TikTok Shop, которые продают рейтинги товаров, оценки продаж, связи авторов с товарами и тренды по категориям через дашборд или API. Перед покупкой задайте три вопроса. Какие рынки покрыты? Цифры продаж наблюдаемые или смоделированные? Можно ли распространять данные внутри компании? Если сервис не может объяснить, откуда берутся его цифры, он продаёт вам оценки, и относиться к ним стоит именно так.
| Путь | Кто может получить | Что покрывает | Данные конкурентов? |
|---|---|---|---|
| TTS API (Partner Center) | Продавцы и разработчики приложений, авторизованные продавцами, авторами или партнёрами | Полный каталог, цены, остатки, заказы, акции, финансы авторизованных магазинов | Нет, только магазины, подключившие ваше приложение |
| Research API, эндпоинты TikTok Shop | Одобренные некоммерческие исследователи | Магазины ЕС: рейтинг и продажи магазина, цена товара и число продаж, отзывы | Да, но только для некоммерческих исследований |
| Аналитические сервисы | Любой, кто платит | Рейтинги, оценки продаж, связи с авторами, история | Да, в рамках лицензии; точность разная |
| Публичные страницы товаров | Любой, кто находится в обслуживаемом рынке | То, что страница показывает незалогиненному посетителю | Да, с учётом ToS и robots.txt |
Публичные страницы TikTok Shop: что доступно в открытом вебе
TikTok Shop — в основном внутриприложенческий опыт, но есть и браузерная витрина на shop.tiktok.com, организованная по рынкам, со страницами товаров по пути /pdp/. Какой рынок вы видите, зависит от того, откуда вы подключаетесь. Когда мы запросили URL www.tiktok.com/shop/pdp/… с сервера в Германии, он вернул редирект 301 на shop.tiktok.com/de/pdp/…. Голый путь www.tiktok.com/shop, запрошенный с той же машины, редиректил на shop.tiktok.com/us.
О покрытии рынков: в ньюсруме TikTok объявили, что Австрия, Бельгия, Нидерланды и Польша запустятся 15 июня 2026 года и присоединятся к Франции, Германии, Ирландии, Италии, Испании и Великобритании. Список регионов в Partner Center (последнее обновление 6 июля 2026 года) также включает США, Мексику, Бразилию, Японию, Индонезию, Малайзию, Филиппины, Сингапур, Таиланд и Вьетнам. Итого 20 рынков с официальным источником. Сторонние списки называют больше, но подтвердить их по собственным страницам TikTok мы не смогли, поэтому здесь они не учтены.
Для сбора из этого следуют три вещи:
- География определяет, что вы видите. У одного и того же товара на каждом рынке могут быть разные цена, валюта, наличие или продавец, а может не быть его вовсе. Чтобы собрать британскую витрину, трафик должен идти из Великобритании. Это главная причина, по которой здесь важны резидентные IP с таргетингом по стране, например
USERNAME-country-GBна резидентном прокси. К маскировке это не имеет отношения. - Страницы сильно зависят от JavaScript. Витрина — это приложение с рендерингом на клиенте. Заголовки ответов
shop.tiktok.comвключаютx-processed-by: Modern.js— это open-source веб-фреймворк ByteDance. Рассчитывайте на то, что понадобится настоящий браузер. - Есть промежуточная страница. С нашего тестового сервера в дата-центре и
shop.tiktok.com/de, иshop.tiktok.com/robots.txtвернули HTML-страницу с заголовком «Security Check», которая загружает скрипт CAPTCHA. На этом мы остановились. Решение или обход этого челленджа выходят за рамки статьи, и если ваш сборщик раз за разом на него натыкается, правильная реакция — замедлиться или остановиться.
Где лежат данные на странице товара
На современных витринах нужные поля редко лежат в аккуратном HTML. Обычно они находятся в одном из трёх мест, в порядке убывания стабильности: блок JSON-LD по схеме schema.org Product/Offer (публикуется для поисковиков, см. документацию Google по разметке товаров), мета-теги Open Graph и товарные мета-теги, а также встроенное состояние гидратации фреймворка — большой JSON внутри тега <script>, который приложение использует для рендеринга без дополнительного запроса.
Приём простой: читайте то, что страница уже вам отправила. JSON-LD и мета-теги разбирайте как документированные форматы. Для состояния гидратации составьте перечень JSON-блоков (их ID и размеры), сами посмотрите один из них в браузере и сопоставьте только нужные поля. Две вещи явно вне рамок: вызов приватных XHR-эндпоинтов, которые приложение использует под капотом, и воспроизведение их параметров подписи или токенов. Подделка подписей — это обход защиты, а не сбор данных. Загрузить страницу товара с тестовой машины нам не удалось (см. промежуточную страницу выше), поэтому утверждать, что на страницах TikTok Shop есть JSON-LD, мы не будем. Код ниже работает одинаково в обоих случаях.
| Показатель | Где обычно находится | Надёжность | Примечания |
|---|---|---|---|
| Название товара | JSON-LD name, og:title, состояние гидратации | Высокая | Может быть локализовано под рынок; используйте как ключ ID товара, а не название |
| Текущая цена | JSON-LD offers.price, состояние гидратации | Средняя | Зависит от рынка, варианта и акции; всегда сохраняйте валюту |
| Базовая цена / скидка | Состояние гидратации; в JSON-LD редко | Ниже средней | Зачёркнутые цены задаёт продавец; считайте скидки сами |
| Число продаж | Состояние гидратации, видимая подпись; Research API (ЕС) | От низкой до средней | Подписи часто сокращены; используйте как тренд, а не как аудированные продажи |
| Рейтинг, количество отзывов | JSON-LD aggregateRating, состояние гидратации | Средняя | Отзывы могут считаться по-разному на разных рынках; в Research API есть распределение оценок для ЕС |
| Название / ID магазина | Состояние гидратации, видимый блок продавца | Высокая | Сохраняйте ID; названия магазинов меняются |
| Категория | JSON-LD хлебных крошек, состояние гидратации | Средняя | Деревья категорий различаются по рынкам; сопоставляйте их с собственной таксономией |
| Варианты / SKU | Состояние гидратации | Средняя | Диапазоны цен скрывают цену варианта, который покупатели выбирают на самом деле |
| Ссылки авторов / партнёров | В основном в приложении; частично в состоянии гидратации | Низкая в вебе | Персональные данные; здесь обычно лучше данные сервисов или партнёров |
Аккуратная схема сбора
Исследовательский сборщик должен вести себя как медленный и честный посетитель. Это значит: по одной странице за раз, фиксированный набор URL, агрессивное кеширование и остановка при челленджах. Условия и правила robots у TikTok обозначают границы яснее, чем у большинства сайтов, так что начнём с них.
Что на самом деле говорят robots.txt и условия
www.tiktok.com/robots.txt (получен 3 октября 2026 года) запрещает /shop/view/product/ для всех user agent и закрывает весь сайт для поименного списка краулеров, в который входят GPTBot, ClaudeBot, CCBot, PerplexityBot и Bytespider. Путь /shop/pdp/ в нём не упоминается, строки Sitemap нет. Прочитать shop.tiktok.com/robots.txt с тестовой машины мы не смогли, потому что вместо него вернулась HTML-страница челленджа. Это ловушка: urllib.robotparser в Python разбирает HTML-страницу как «нет правил», то есть «разрешено всё». Код ниже доверяет только ответу 200 с обычным текстом.
Условия строже, чем robots.txt. Условия использования для США (соглашение с TikTok USDS Joint Venture LLC, последнее обновление 15 июля 2026 года) запрещают скрейпинг или извлечение данных «for any purpose, from the Platform using any automated system or software… except as approved in writing» («с любой целью, с Платформы с помощью любой автоматизированной системы или программы… кроме случаев письменного одобрения»). Условия для ЕЭЗ говорят примерно то же. Обязывают ли они незалогиненного посетителя, зависит от юрисдикции, но это веская причина предпочесть официальные и лицензированные пути.
Правила проектирования и их причины
- Начинайте с известного списка URL, а не с обхода. Исследовательские вопросы касаются конкретных товаров или выборки. Именно при обходе страниц поиска и категорий накапливаются нагрузка и риски по ToS, да и robots.txt у TikTok всё равно запрещает пути
/search?. - Один рынок на прогон, и зафиксируйте его. Таргетируйте выходной IP по стране и выставьте в браузере соответствующие локаль и часовой пояс, чтобы все наблюдения в пакете относились к одному рынку.
- Держите низкую частоту. Одной страницы раз в 20–40 секунд на рынок с лихвой хватает для ежедневных ценовых снимков нескольких сотен товаров.
- Кешируйте по ключу (ID товара, рынок, день). Если сегодняшнее британское наблюдение уже есть, не запрашивайте его снова.
- Считайте челлендж сигналом остановки. Залогируйте его, подождите и снизьте частоту. Не ротируйте IP, чтобы обойти ту же блокировку.
- Не логиньтесь. Собирайте только то, что видит незалогиненный посетитель. Сбор под логином привязывает автоматизацию к аккаунту и его условиям и затрагивает персональные данные.
Аккуратный пример на Python с Playwright
Скрипт ниже открывает каждый URL товара в Chromium через прокси с таргетингом по стране. Сначала он проверяет настоящий robots.txt, останавливается на ответах, отличных от 200, или на заголовке «Security Check» и извлекает данные Product из JSON-LD, несколько мета-тегов и список встроенных JSON-блоков для ручного изучения. Специфичных для TikTok селекторов в нём нет, потому что проверить их мы не смогли, и каждое отсутствующее поле возвращается как None. Настройки прокси соответствуют документированной опции proxy в Playwright. Логику извлечения и обработки robots мы проверили на локальных фикстурах с Playwright 1.55. На живых страницах TikTok Shop мы его не запускали.
import json
import random
import time
import urllib.robotparser
from urllib.parse import urlsplit
from playwright.sync_api import sync_playwright
# Страна задаётся в имени пользователя прокси; локаль и часовой пояс подстройте под неё.
PROXY = {
"server": "http://gate.proxyhat.com:8080",
"username": "USERNAME-country-GB",
"password": "PASSWORD",
}
UA_NAME = "acme-price-research" # токен, который стоит искать в группах robots.txt
# URL товаров, которые у вас уже есть (из сопоставления с вашим каталогом, выгрузки
# партнёра или ручного исследования), а не найденные обходом страниц поиска.
URLS = [
"https://shop.tiktok.com/...", # вставьте реальные URL товаров так, как их показывает браузер
]
def robots_verdict(context, url):
"""Return True/False from a real robots.txt, or None if we couldn't get one."""
parts = urlsplit(url)
resp = context.request.get(f"{parts.scheme}://{parts.netloc}/robots.txt")
ctype = resp.headers.get("content-type", "")
# HTML-страница челленджа разбирается в urllib.robotparser как «нет правил»
# (= разрешено всё), поэтому доверяем только ответу 200 с text/plain.
if resp.status != 200 or "text/plain" not in ctype:
return None
rp = urllib.robotparser.RobotFileParser()
rp.parse(resp.text().splitlines())
return rp.can_fetch(UA_NAME, url)
def _types(node):
t = node.get("@type", [])
return t if isinstance(t, list) else [t]
def extract(page):
"""Read what the page itself publishes: JSON-LD, Open Graph/product meta,
and an inventory of embedded JSON blobs for a human to inspect."""
jsonld = []
for raw in page.locator('script[type="application/ld+json"]').all_text_contents():
try:
data = json.loads(raw)
except json.JSONDecodeError:
continue
nodes = data if isinstance(data, list) else data.get("@graph", [data])
jsonld.extend(n for n in nodes if isinstance(n, dict))
meta = {}
for prop in ("og:title", "og:url", "product:price:amount", "product:price:currency"):
loc = page.locator(f'meta[property="{prop}"]')
if loc.count():
meta[prop] = loc.first.get_attribute("content")
blobs = page.evaluate(
"""() => [...document.querySelectorAll('script[type="application/json"]')]
.map(s => ({id: s.id || null, chars: s.textContent.length}))"""
)
product = next((n for n in jsonld if "Product" in _types(n)), None)
record = {"name": None, "price": None, "currency": None,
"availability": None, "rating": None, "review_count": None}
if product:
record["name"] = product.get("name")
offers = product.get("offers") or {}
if isinstance(offers, list):
offers = offers[0] if offers else {}
record["price"] = offers.get("price") or offers.get("lowPrice")
record["currency"] = offers.get("priceCurrency")
record["availability"] = offers.get("availability")
agg = product.get("aggregateRating") or {}
record["rating"] = agg.get("ratingValue")
record["review_count"] = agg.get("reviewCount") or agg.get("ratingCount")
return {"record": record, "meta": meta, "json_blobs": blobs,
"has_jsonld_product": product is not None}
def main():
results = []
with sync_playwright() as p:
browser = p.chromium.launch(proxy=PROXY)
context = browser.new_context(locale="en-GB", timezone_id="Europe/London")
page = context.new_page()
for url in URLS:
verdict = robots_verdict(context, url)
if verdict is not True:
results.append({"url": url, "status": "skipped", "robots": verdict})
continue
resp = page.goto(url, wait_until="domcontentloaded", timeout=45_000)
status = resp.status if resp else None
if status != 200 or page.title().strip().lower() == "security check":
# Не пытаемся его решать. Записываем, замедляемся, идём дальше.
results.append({"url": url, "status": "challenge_or_error", "http": status})
time.sleep(120)
continue
data = extract(page)
data.update({"url": url, "final_url": page.url, "status": "ok",
"fetched_at": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
"proxy_country": "GB"})
results.append(data)
time.sleep(random.uniform(20, 40)) # по одной странице за раз, медленно
browser.close()
print(json.dumps(results, indent=2, ensure_ascii=False))
if __name__ == "__main__":
main()
Если has_jsonld_product возвращается как false, посмотрите на json_blobs. Откройте один товар в обычном браузере, найдите блок, в котором лежит цена, и напишите небольшое явное сопоставление для двух-трёх нужных ключей. Добавьте тест, который громко падает, когда эти ключи переезжают. Более широкий взгляд на сторону JavaScript — в статье о скрейпинге сайтов, перегруженных JavaScript.
Подводные камни качества данных
Большинство датасетов по TikTok Shop портятся на этапе анализа, а не сбора. Цены сравнивают между рынками без нормализации, акционные цены принимают за базовые, а округлённые числа продаж — за показатели продаж.
- Регион и валюта. В каждой строке храните рынок, валюту и страну выхода. Конвертируйте валюты по курсу на дату наблюдения и никогда не усредняйте цены между рынками.
- Флеш-распродажи и акции. Короткие акции могут на часы сдвинуть отображаемую цену. Делайте снимки в одно и то же время каждый день и записывайте и показанную цену, и базовую, чтобы распродажу не приняли за постоянное снижение.
- Округление числа продаж. Отображаемые числа часто сокращены, и даже точное целое в данных страницы — это цифра платформы, а не аудированное значение. Используйте разницу во времени и ожидайте ступенек, а не плавных кривых.
- Каталоги под конкретный рынок. Товар, которого нет на одном рынке, не обязательно закончился. Возможно, его там просто не продают. Разделяйте «недоступен на рынке» и «нет в наличии».
Те же проблемы встречаются и на других маркетплейсах, о которых мы писали. В руководстве по ценовой аналитике Shein разобраны региональные витрины, в руководстве по данным товаров Temu — встроенный JSON, а в руководстве по Shopify — документированные публичные эндпоинты товаров, что полезно для сравнения с платформами, где их нет.
Правовые и этические границы
Публичные карточки товаров — наименее рискованная часть этого датасета. Авторы — самая рискованная. Цена товара — коммерческая информация, а никнейм автора, его профиль и партнёрская активность являются персональными данными по GDPR, если относятся к идентифицируемому человеку. Для работы в ЕС или Великобритании их сбор требует законного основания, минимизации данных и ограничения срока хранения, даже если профиль публичный. Где можно, агрегируйте — например, «товары, которые продвигают более 50 авторов», — вместо того чтобы строить профили отдельных людей.
Сверху ложатся условия TikTok, процитированные выше, и вопрос товарных знаков: описывайте TikTok Shop фактически и не выдавайте свой датасет или инструмент за связанный с ним. Если исследование коммерческое и постоянное, официальный или лицензированный путь почти всегда надёжнее в долгую. Сборщик публичных страниц лучше всего подходит для узких проверок небольшого объёма, которые официальные пути не покрывают, — например, чтобы подтвердить, что британский покупатель видит именно сегодня.
Чего этот подход не решает
Аккуратный сборщик публичных страниц не даст полного покрытия категорий, атрибуции авторов, продаж в прямых эфирах или контента, доступного только в приложении. Он не пройдёт промежуточные страницы и не должен пытаться. За несколько месяцев он к тому же сломается по мере изменений фронтенда. Если вам нужно что-то из этого, это вопрос лицензирования данных, а не инженерии. Для сетевой части того, что остаётся, на нашей странице о веб-скрейпинге и в списке локаций указано, через какие страны можно направлять трафик.






