Ищем фильмы, книги и подкасты с помощью Python

    Пакет podsearch для поиска подкастов


    Apple не особо афиширует, что у iTunes Store и других каталогов есть кривенькое, но простое поисковое API — поэтому я решил о нём написать. Из этой заметки вы узнаете, что API умеет и как его использовать.


    Поиск в каталогах Apple


    API ищет по содержимому iTunes Store, iBooks Store, Apple Podcasts и App Store. Соответственно, можно найти песни, фильмы, книги, подкасты и приложения.


    API работает по давно забытому принципу JSONP, то есть возвращает Content-Type: text/javascript вместо нормального application/json.


    GET /search?media=podcast&term=python HTTP/1.1
    Host: itunes.apple.com
    Accept: application/json
    
    HTTP/2 200
    content-type: text/javascript; charset=utf-8
    
    {...}

    Конечно, эту особенность можно просто игнорировать:


    import requests
    
    def search(term, media):
        url = "https://itunes.apple.com/search"
        payload = {"term": term, "media": media}
        response = requests.get(url, params=payload)
        response.raise_for_status()
        results = response.json().get("results", [])
        return results

    >>> results = search("python", media="podcast")
    >>> results[0]["collectionName"]
    'Talk Python To Me'

    Параметры запроса


    Поиск можно настроить:


    • term — поисковый запрос, единственный обязательный параметр;
    • media — тип произведения (movie, podcast, music, audiobook, software, ebook, all), по умолчанию all;
    • country — страна произведения, двухсимвольный ISO-код (us, ru, ...), по умолчанию us;
    • limit — максимальное количество результатов, по умолчанию 50.

    Пример функции, которая поддерживает все параметры:


    import requests
    
    def search(term, media="all", country="us", limit=10):
        url = "https://itunes.apple.com/search"
        payload = {"term": term, "media": media, "country": country, "limit": limit}
        response = requests.get(url, params=payload)
        response.raise_for_status()
        results = response.json().get("results", [])
        return results

    Ответ


    Общая структура ответа:


    {
        "resultCount": 10,
        "results": [
            {
                "wrapperType": "track",
                "kind": "song",
                "artistId": 1495668306,
                "collectionId": 527039271,
                "trackId": 527039276,
                "artistName": "Dodge & Fuski",
                "collectionName": "Never Say Die (Deluxe Edition)",
                "trackName":"Python",
                ...
            }, 
            {
                "wrapperType": "track",
                "kind": "podcast",
                "collectionId": 979020229,
                "trackId": 979020229,
                "artistName": "Michael Kennedy (@mkennedy)",
                "collectionName": "Talk Python To Me"
                ...
            },
            ...
        ]
    }

    Конкретный набор полей зависит от типа произведения (kind) и полноценно нигде не описан, насколько мне известно. Часто заполнены:


    • artistId — идентификатор автора произведения;
    • artistName — автор;
    • artistViewUrl — ссылка на автора на сайте Apple;
    • collectionId — идентификатор альбома;
    • collectionName — название альбома;
    • collectionViewUrl — ссылка на альбом на сайте Apple;
    • trackId — идентификатор композиции;
    • trackName — название композиции;
    • artworkUrl100 — ссылка на превьюшку произведения 100x100 пикселей;
    • country — страна произведения;
    • primaryGenreName — жанр произведения.

    Для подкастов я сделал типизированную обёртку — пакет podsearch, можно посмотреть набор полей в нём.


    Запрос по идентификатору


    Если известен идентификатор объекта (artistId, collectionId, trackId), можно вызвать метод lookup по нему:


    import requests
    
    def lookup(object_id):
        url = "https://itunes.apple.com/lookup"
        payload = {"id": object_id}
        response = requests.get(url, params=payload)
        response.raise_for_status()
        results = response.json().get("results", [])
        return results

    >>> results = lookup(979020229)
    >>> results[0]["collectionName"]
    'Talk Python To Me'

    Нюансы


    Про необычный Content-Type ответа я уже упомянул. Кроме того:


    • Страна произведения (country) есть как в параметрах запроса, так и в ответе. Но в параметрах это двухсимвольный ISO-код (ru), а в ответе — трёхсимвольный (RUS).
    • Схемы ответа не существует.
    • Apple ограничивает частоту вызова API 20 запросами в минуту.

    Описание API на сайте Apple
    Пакет для поиска по подкастам


    Если хотите больше интересных штук на Python — подписывайтесь на канал @ohmypy

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 3

      0
      почему все используют requests а не aiohttp?
        0

        Думаю, в данном случае это не имеет значения — код для иллюстрации работы API. А так хоть httpx, хоть aiohttp можно использовать.

          0
          почему все используют requests
          потому что requests — для людей.

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое