При поиске видео в TikTok через API ролики могут находиться не в том массиве, который первым ожидает обработчик. В проверенном ответе jsonscraper на запрос `/searchVideo` поле `aweme_list` было пустым, а элементы с данными видео находились в `search_item_list[].aweme_info`. Если код читает только `aweme_list`, он сохранит ноль роликов, хотя ответ содержит найденные видео. Для разработчика это конкретная задача надёжности: извлечь обе формы данных и нормализовать их в единый список до записи в базу или отправки в отчёт.
![Article: Как не потерять TikTok-результаты поиска при разборе JSON
Summary: Практический разбор поиска TikTok: endpoint `/searchVideo` может отдавать пустой `aweme_list`, а найденные ролики — в `search_item_list[].aweme_info`. Показываем Python-нормализацию обеих структур с дедупликацией по ID.
Image role: cover — the central idea
Section: Как не потерять TikTok-результаты поиска при разборе JSON
Visual subject: Editorial photograph illustrating TikTok API JSON normalization: two distinct stream](/assets/uploads/journal/2026/11/3f9ca6f48040b3044b8190c9a7b7a847.png.hero.webp)
Проверка живого примера и описания маршрута доступна в спецификации API jsonscraper и документации TikTok endpoint. Снимок схемы в спецификации датирован 25 октября 2026 года; он демонстрирует структуру конкретного ответа, а не гарантирует наличие каждого поля в каждом последующем запросе.
Почему парсер может вернуть пустой список
Маршрут `GET https://tiktok.evelode.com/searchVideo` ищет видео по обязательному параметру `keyword`. Документация также перечисляет `cursor`, `count`, `cache_timeout`, `date_posted`, `sort_by` и `region`. В схеме наблюдавшегося ответа верхний объект содержит `status` и вложенный объект `tiktok`; внутри него — `cursor`, `has_more`, `status_code`, `aweme_list` и `search_item_list`.
В конкретном наблюдении для запроса с ключевым словом и `count=3` массив `aweme_list` оказался пустым. В то же время `search_item_list` включал элементы, у которых сведения о видео лежали в `aweme_info`. В этих объектах могли присутствовать ID видео, подпись, URL публикации, автор и статистика, например число просмотров, лайков или комментариев. Описанные поля отражают наблюдённую схему; обработчик всё равно должен принимать отсутствующие значения.
Практический вывод состоит в том, что успешный HTTP-запрос и непустой массив в одном ожидаемом поле — разные проверки. Сначала проверьте внешний статус и наличие `tiktok`, затем соберите ролики из каждого документированного места. Для аналитики сохраняйте ID и исходный ответ: так можно проследить, как конкретная запись была извлечена и нормализована.
Нормализуйте ответ до записи в хранилище
Удобная граница между API и собственной системой — функция, которая принимает вложенный объект `tiktok` и возвращает унифицированные элементы. Она должна обрабатывать оба массива, пропускать несловарные или пустые элементы, а также устранять повтор одного ролика по `aweme_id`. Счётчики оставляйте пустыми, когда провайдер их не вернул: ноль означал бы измеренное значение, тогда как `None` сообщает об отсутствии поля.
Ниже минимальный пример для Python 3.8+. Он выполняет один запрос, проверяет транспортный и верхнеуровневый статус, нормализует два варианта результата и печатает выбранные поля. Ключ читается из переменной окружения и не выводится в лог.
import os
import requests
BASE_URL = "https://tiktok.evelode.com"
def extract_videos(tiktok):
candidates = []
aweme_list = tiktok.get("aweme_list") or []
if isinstance(aweme_list, list):
candidates.extend(aweme_list)
search_items = tiktok.get("search_item_list") or []
if isinstance(search_items, list):
for item in search_items:
if isinstance(item, dict):
candidates.append(item.get("aweme_info"))
unique = {}
for video in candidates:
if not isinstance(video, dict):
continue
video_id = video.get("aweme_id")
if video_id:
unique[video_id] = video
return list(unique.values())
license_key = os.environ["JSONSCRAPER_TIKTOK_LICENSE_KEY"]
response = requests.get(
BASE_URL + "/searchVideo",
params={
"license_key": license_key,
"keyword": "python tutorial",
"count": 10,
"region": "US",
},
timeout=30,
)
response.raise_for_status()
payload = response.json()
if payload.get("status") != "ok":
raise RuntimeError("TikTok API returned a non-ok status")
tiktok = payload.get("tiktok")
if not isinstance(tiktok, dict):
raise RuntimeError("Response has no tiktok object")
for video in extract_videos(tiktok):
stats = video.get("statistics") or {}
author = video.get("author") or {}
print({
"aweme_id": video.get("aweme_id"),
"desc": video.get("desc"),
"share_url": video.get("share_url"),
"author": author.get("unique_id"),
"play_count": stats.get("play_count"),
"digg_count": stats.get("digg_count"),
"comment_count": stats.get("comment_count"),
})
Установите зависимость командой python -m pip install requests, задайте `JSONSCRAPER_TIKTOK_LICENSE_KEY` в среде запуска и сохраните файл, например, как `search_videos.py`. Параметры запроса совпадают с документированными именами: `keyword`, `count` и `region`; `license_key` передаётся как query-параметр. Код предполагает, что ответ содержит `status: "ok"`, как в зафиксированном примере. Если API возвращает другой статус, обработка останавливается до передачи сомнительной структуры дальше.
Как превратить пример в повторяемый сбор
Для разового экспорта достаточно записать нормализованные элементы в JSON Lines или таблицу. В постоянном процессе добавьте сохранение исходного ответа вместе с временем получения и поисковым запросом. Отдельная таблица нормализованных роликов может использовать `aweme_id` как ключ: повторный результат обновляет запись, а повтор одного ID в двух массивах не создаёт дубликат.
![Article: Как не потерять TikTok-результаты поиска при разборе JSON
Summary: Практический разбор поиска TikTok: endpoint `/searchVideo` может отдавать пустой `aweme_list`, а найденные ролики — в `search_item_list[].aweme_info`. Показываем Python-нормализацию обеих структур с дедупликацией по ID.
Image role: supporting illustration 2 — a different specific aspect
Section: Как превратить пример в повторяемый сбор
Visual subject: Technical infographic in Russian showing documented TikTok search resp](/assets/uploads/journal/2026/11/66c0aca83032161e7952e46e3d545a92.png.hero.webp)
Чтобы запросить следующую страницу, документация указывает параметр `cursor`: передавайте значение, полученное в предыдущем ответе. Считайте его непрозрачным токеном — храните и возвращайте без преобразований. Цикл пагинации должен завершаться при отсутствии продолжения по `has_more` или когда API не предоставляет пригодный курсор; ограничьте число страниц на один запуск, чтобы ошибочная логика не создала бесконечный цикл. Зафиксированные источники подтверждают имя параметра и наличие полей `cursor` и `has_more` в наблюдавшейся схеме, но не задают гарантию полноты результатов.
Для мониторинга нескольких поисковых фраз храните фразу рядом с ID ролика и временем сбора. Тогда можно строить срезы по запросам, сравнивать выдачи между запусками и отправлять новые ID в очередь дальнейшей классификации. Такая система описывает полученные результаты поиска; её набор данных зависит от запроса, региона, времени и фактически возвращённых API элементов.
Проверяйте качество данных, а не только успешность запроса
После нормализации полезно вести простые технические показатели своего пайплайна: число записей из каждого массива, число уникальных ID, долю элементов без ID и долю элементов без статистики. Это метрики обработки конкретного ответа, а не оценки популярности видео. Например, рост числа элементов без `play_count` говорит о том, что аналитике следует сохранить неизвестное значение и отметить полноту поля, вместо того чтобы подставлять ноль.
Не привязывайте дальнейший расчёт к тому, что у каждого видео обязательно есть одинаковый набор статистики. Для сохранения сырых данных оставьте весь JSON; для аналитической таблицы выбирайте только нужные поля и допускайте `NULL`. При изменении формы ответа исходный архив позволит повторно запустить нормализатор без повторного запроса.
Ключ API передавайте через секреты CI или переменные окружения оркестратора. Не включайте его в URL, сохраняемые в журналы, не печатайте объект параметров запроса и не сохраняйте значение ключа рядом с исходными ответами. Если работа запускается по расписанию, добавьте ограничение времени запроса, обработку HTTP-ошибок и повторные попытки с паузой; храните курсор только вместе с конкретным поисковым запросом, чтобы не смешивать страницы разных выдач.
Результат: единая таблица вместо пропущенных роликов
После нормализации downstream-код получает один список видео вне зависимости от того, пришёл элемент в `aweme_list` или в `search_item_list[].aweme_info`. ID позволяет удалить повторы, а необязательные поля остаются явно пустыми. Это уменьшает риск пустых отчётов из-за чтения только одного массива и делает следующий этап — выгрузку, фильтрацию или классификацию — предсказуемым.
Начать проверку можно с страницы TikTok Scraper API, где указана базовая точка API и доступен переход к демо. Для интеграции используйте официальную документацию и сначала проверьте обработку на малом числе элементов; при необходимости увеличивайте `count` и продолжайте выдачу документированным курсором. Результатом будет аккуратный слой данных для ваших задач, а не предположение о полном охвате TikTok.