Переносим треки из и в Spotify с помощью Python

Переносим треки из и в Spotify с помощью Python

Первую часть пути мы пройдем окольным путем: чтобы чему-то научиться откажемся от использования неофициальной библиотеки yandex-music-api и получим данные своими руками. Во второй части пути к нам на помощь придет библиотека spotipy, которая перенесет в Спотифай все личные плейлисты, лайкнутые треки и альбомы. Поехали!

Переносим альбомы

У Яндекс.Музыки (ЯМ) нет API. Совсем. Поэтому данные нам придется брать со страниц ЯМ. Перейдем на свою страницу ЯМ в раздел альбомы и начнем поиск информации, открыв инструменты разработчика ( Ctrl + Shift + i в Chrome и FireFox).

В теле страницы с альбомами есть JSON-массив Mu , который в двух ключах содержит все, что нам нужно знать об альбоме: его ID, название и имя исполнителя:

Переносим треки из и в Spotify с помощью Python

C массивом Mu будем работать постоянно, так как в нем содержится самое ценное – ID альбомов, плейлистов и треков, по которому мы получаем всю необходимую информацию. Поэтому ID будет нашей целью на всем пути следования.

  • Первый ключ – albumIds – содержит ID всех альбомов, но нам нужно будет дополнительно переходить на страницу каждого альбома и получать его название и имя исполнителя из тегов.
  • Второй ключ – albums – сразу выдает название альбома и имя исполнителя, но только первые 150 пар (это ограничение распространяется на плейлисты тоже).

Мы воспользуемся первым ключом, чтобы перенести все альбомы.

Как вывести json в более читаемом виде, как на картинке выше?

Через функцию pprint :

Как получить название альбома и имя исполнителя?

Получив ID, перейдем на страницу альбома https://music.yandex.ru/album/ID_альбома . Из тегов узнаем название альбома и имя исполнителя. Допустим, в нашей фонотеке есть альбом «Greatest Hits In Japan» – Queen. Откроем страницу альбома .

В браузере перейдем в инструменты разработчика и выберем инструмент Селектор ( Ctrl + Shift + C ):

Переносим треки из и в Spotify с помощью Python

И просто кликнем по названию альбома на странице:

Переносим треки из и в Spotify с помощью Python

Тег <h1> с названием альбома найдется автоматически:

Переносим треки из и в Spotify с помощью Python

Тег <a> с именем исполнителя:

Переносим треки из и в Spotify с помощью Python

Автоматизация получения данных, Selenium

Библиотека Selenium умеет управлять браузером и часто используется для автоматизации тестирований. С помощью Selenium мы автоматизируем действия браузера: открытие страниц плейлистов, альбомов и треков.

Установим драйвер Chrome:

Chromedriver установится в /usr/lib/chromium-browser/chromedriver

Алгоритм получения данных об альбоме:

  1. Зайти на страницу со своими/чужими альбомами.
  2. Получить ID альбомов из массива Mu .
  3. Перейти на страницу альбома и найти в тегах название альбома и имя исполнителя.

Создадим в корневой директории папку proglib , а в ней файл get_music_data.py .

Импортируем Selenium и напишем функцию run_driver() , запускающую браузер:

  • ‘chromedriver’ – путь к драйверу. Либо можем записать полный путь: ‘/usr/lib/chromium-browser/chromedriver’ .

Дальше идет небольшой велосипед. Дело в том, что Selenium при извлечении массива Mu со страницы ЯМ выдает ошибку:

Пауза после загрузки, чтобы страница загрузилась до конца и листание в конец страницы не помогли, другие подходы – тоже. Оказалось, если сохранить страницу на локальной машине, то можно вытащить всю информацию из массива Mu без каких-либо проблем. Сделаем это.

Алгоритм следующий:

  1. Обратиться к странице ЯМ.
  2. Создать локальную html-страницу и скопировать в нее содержимое страницы ЯМ.
  3. Извлечь массив Mu .
  4. Удалить локальную страницу.

Напишем функцию create_local_html_page() , которая создает локальный html-файл и заполняет ее содержимым страницы из ЯМ:

  • page_filename – название html-файла.
  • page_source – код страницы ЯМ.

Теперь напишем функцию get_local_html_page() , которая с помощью Selenium открывает локальную страницу:

  • yandex_username – имя пользователя ЯМ.
  • page_filename – название html-файла.
  • url – ссылка на ЯМ.

И, наконец, функция delete_local_html_page() удаляет локальную страницу:

  • page_path – путь к html-файлу.

Получим название альбома и имя исполнителя. Создадим функцию get_albums() :

В этом блоке кода мы:

  1. Создаем ссылку на страницу альбомов ЯМ пользователя.
  2. Создаем локальную страницу всех альбомов.
  3. Получаем всю информацию об альбомах из массива Mu .
  4. Получаем ID всех альбомов.
  5. Создаем словарь albums_for_spotify , в который запишем название альбома и имя исполнителя.

Здесь происходит следующее:

  1. Переходим на страницу альбома ЯМ.
  2. Создаем вложенный словарь для каждого альбома, в который записываем название альбома и имя исполнителя.
  3. Метод xpath позволяет искать вложенные друг в друга теги и извлекать из них текст. С его помощью найдем в коде страницы тег <h1> с классом deco-typo . И получим текст, содержащийся в теге с помощью .text .
  4. Записываем в словарь название альбома и имя исполнителя.
  5. Удаляем локальную страницу со всеми альбомами ЯМ.
  6. Закрываем браузер

В итоге словарь выглядит так:

Данные получили, как их перенести?

За перенос треков отвечает библиотека spotipy. Установим ее:

Для начала нужно создать приложение в Спотифай, получить client_id и client_secret . Зайдем на страницу developer.spotify.com/dashboard

И кликнем на Create an app :

Создание приложения в SpotifyСоздание приложения в Spotify

заполним поля и нажмем Create :

Переносим треки из и в Spotify с помощью Python

После создания приложения кликнем по нему и найдем Client ID и Client Secret :

Получение Client ID и Client Secret в приложении SpotifyПолучение Client ID и Client Secret в приложении Spotify

Зайдем в настройки приложения:

Переносим треки из и в Spotify с помощью Python

и впишем в поле Redirect URIs адрес http://localhost:8888/callback/ :

Редактирование поля Redirect URIs в приложении SpotifyРедактирование поля Redirect URIs в приложении Spotify

Сохраним и закроем.

Дальше нам понадобится второй файл transfer.py для авторизации в Spotify через библиотеку spotify и для переноса альбомов (а также плейлистов, но об этом позже).

Запишем в transfer.py следующие строчки:

  • scope – права приложения.
  • redirect_uri – ссылка, которая откроется (и сразу закроется) в браузере при получении прав доступа.
  • username – имя пользователя в Спотифай.

Напишем функцию get_album_id() , которая ищет в спотифай ID альбома:

  • sp.search(q=query, limit=1, type=’album’) – поисковый запрос query выдает первый результат из раздела альбомы.
  • В итоге функция возвращает ID альбома. А метод split делает из строки список, потому что метод current_user_saved_albums_add() , добавляющий в Спотифай альбом по ID, принимает в качестве аргумента именно список.

Перенесем альбомы через функцию transfer_albums() :

  • sp, username = autorisation() – авторизация в Спотифай.
  • query = ‘ ‘.join([artist_name, album_title]) – формируем поисковый запрос из названия альбома и имени исполнителя.
  • get_album_id(query, sp) – ищем в Спотифай альбом по ID.
  • sp.current_user_saved_albums_add(album_id) – добавляем альбом в свою медиатеку.
  • except: pass – если альбом не найден (функция get_album_id вернет нам IndexError или KeyError ), то пропустить и начать сначала.

Переносим плейлисты

Плейлисты делятся на два вида:

  • Плейлист «Мне понравилось» и созданные пользователем плейлисты.
  • Лайкнутые плейлисты.

Мои плейлисты

  1. Перейти на странцу всех плелистов пользователя https://music.yandex.ru/users/yandex_username/playlists/ .
  2. Получить ID плейлистов из массива Mu .
  3. Перейти на страницу плейлиста по его ID.
  4. Получить со страницы плейлиста ID треков из массива Mu .
  5. Перейти на страницу каждого трека и получить их названия и имена исполнителей из тегов.

Вернемся к файлу get_music_data.py и добавим в него функцию get_my_playlists_id для получения ID альбомов на ЯМ:

Также как с альбомами: переходим на страницу всех плейлистов, извлекаем данные из массива Mu , находим ключ playlistIds с ID всех плейлистов.

Напишем функцию get_my_playlists для переноса своих плейлистов:

В этой части кода мы получаем ID всех наших плейлистов и записываем в словарь my_playlists , их ID и названия.

Теперь получим названия трека и имя исполнителя:

  • track_id = re.findall(r’\d+(?=:)’, all_track_ids[j])[0] – all_track_ids имеет вид ID_трека:ID_плейлиста . Используем регулярное выражение, чтобы получить все числа до двоеточия – ID трека.
  • driver.find_elements_by_xpath(“//span[@class=’d-artists’]//a[@class=’d-link deco-link’]”)[0].text – возвращает список, где первый элемент – имя первого исполнителя, если их несколько или единственного, если он записал трек соло.

В итоге словарь my_playlists_for_spotify выглядит так:

Теперь перенесем плейлисты в Спотифай. Откроем файл transfer.py и напишем функцию get_track_id() для поиска ID трека в Спотифай:

sp.search(q=query, limit=1, type=’track’) – получаем первый результат поискового запроса query .

Напишем функцию transfer_playlists , которая будет переносить как плейлисты пользователя, так и лайкнутые:

create_spotify_playlist – создает пустой плейлист в Спотифай с названием из ЯМ.

number_of_tracks – количество треков в плейлисте.

  1. Здесь мы ищем в Спотифай треки и записываем их ID и название плейлиста в словарь new_spotify_playlist .
  2. if all(query == ” for query in new_spotify_playlist.values()) – если все значения словаря пустые, значит треки отсутствуют в каталоге Спотифай, например, подкасты или локальные исполнители.
  3. sp.user_playlist_unfollow(username, new_spotify_playlist_id) – удаляет пустой плейлист из Спотифай.

Лайкнутые плейлисты

Лайкнутые плейлисты создали другие пользователи, но мы можем их перенести также как свои плейлсты. Откроем файл get_music_data и напишем функцию get_liked_playlists_data() , которая создает словарь с ID лайкнутых плейлистов, их названиями и именами пользователей, создавших плейлист.

Здесь мы переходим на страницу своих плейлистов, извлекаем содержимое из массива Mu и создаем словарь с ID плейлиста, его названием и именем пользователя создавшего плейлист.

Теперь напишем функцию get_liked_playlists() , которая переходит на страничку лайкнутых плейлистов и получает названия треков и исполнителей

В этом блоке кода мы:

  1. Переходим на страницу плейлиста.
  2. Получаем ID треков в формате ID_трека:ID_альбома .
  • С помощью регулярного выражения получаем ID трека.
  • Переходим на страницу трека.
  • Получаем название трека и имя исполнителя.
  • Записываем в словарь название плейлиста, его треки и имена исполнителей.

Лайкнутые плейлисты переносим через функцию transfer_playlsits() .

Запускаем миграцию музыки

В конце файла transfer.py напишем функцию main() , которая перенесет всю фонотеку в Спотифай.

Альбомы переносятся так:

Переносим треки из и в Spotify с помощью Python

Мы написали скрипт для переноса всей фонотеки из Яндекс.Музыки в Спотифай и научились: