Формат ответа
Один объект, всегда одинаковый. Поле, которое не применимо, приходит как null, а не исчезает — поэтому вашему парсеру не нужно проверять, есть ли ключ.
Верхний уровень
| Поле | Тип | Примечание |
|---|---|---|
platform | string | Какой площадке принадлежала ссылка: instagram, youtube, tiktok, facebook, vk, threads, twitter, reddit или pinterest |
type | string | video, image, album либо audio, если у YouTube просили mp3 |
title | string | null | Подпись или название видео, если у поста они есть |
author | string | null | Имя аккаунта или канала, если площадка его сообщает |
thumbnail | string | null | Картинка предпросмотра |
duration | number | null | Длительность в секундах, если площадка её сообщает |
media | array | Всегда есть, всегда хотя бы один элемент |
Внутри media
| Поле | Тип | Примечание |
|---|---|---|
type | string | video, image или audio |
url | string | Прямая ссылка на один файл. У видео звук уже внутри, склеивать после ничего не нужно. |
quality | string | null | Высота, в которой VK закодировал этот вариант, подписью вида 1080p, либо формат, который вы попросили у YouTube. Везде остальное null. |
ext | string | null | mp4 или mp3 там, где площадка это сообщает, и null там, где нет |
Что заполнено всегда
platform, type и media всегда что-то содержат. Остальные четыре — нет: одна и та же площадка на одной ссылке вернёт автора, а на следующей null. Считайте все четыре необязательными, и сюрпризов не будет.
Единственный эндпоинт с другой формой
/v2/youtube/info ничего не качает, поэтому и класть в media ему нечего. Вместо этого он отвечает фактами о ролике: id, author_url, все размеры превью и массив formats, где у каждого качества указан размер в байтах. Это тело показано на странице YouTube.
Как под это писать
data = response.json()
if data["type"] == "album":
print(len(data["media"]), "files")
for item in data["media"]:
download(item["url"])