Share This
Π‘Π²ΡΠ·Π°Ρ‚ΡŒΡΡ со ΠΌΠ½ΠΎΠΉ
ΠšΡ€ΡƒΡ‚ΠΈ Π² Π½ΠΈΠ·
Categories
//🎼 ΠŸΠ΅Ρ€Π΅Π½ΠΎΡΠΈΠΌ Ρ‚Ρ€Π΅ΠΊΠΈ ΠΈΠ· ЯндСкс.ΠœΡƒΠ·Ρ‹ΠΊΠΈ Π² Spotify с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Python

🎼 ΠŸΠ΅Ρ€Π΅Π½ΠΎΡΠΈΠΌ Ρ‚Ρ€Π΅ΠΊΠΈ ΠΈΠ· ЯндСкс.ΠœΡƒΠ·Ρ‹ΠΊΠΈ Π² Spotify с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Python

Используя Python и Selenium, получим все плейлисты и альбомы из Яндекс.Музыки, а с помощью библиотеки spotipy перенесем фонотеку в Спотифай.

perenosim treki iz jandeksmuzyki v spotify s pomoshhju python 08c7934 - 🎼 Переносим треки из Яндекс.Музыки в Spotify с помощью Python

Возможности скрипта:

  • перенос альбомов;
  • перенос своих плейлистов и треков из плейлиста «Мне нравится»;
  • перенос лайкнутых плейлистов.

Единственное условие: фонотека Яндекс.Музыки должна быть открытой. ***

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

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

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

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

perenosim treki iz jandeksmuzyki v spotify s pomoshhju python ab14955 - 🎼 Переносим треки из Яндекс.Музыки в Spotify с помощью Python

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

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

perenosim treki iz jandeksmuzyki v spotify s pomoshhju python 654f2bc - 🎼 Переносим треки из Яндекс.Музыки в Spotify с помощью Python

JSON Яндекс.Музыки

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

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

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

         from pprint import pprint pprint(json)     

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

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

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

perenosim treki iz jandeksmuzyki v spotify s pomoshhju python ed67287 - 🎼 Переносим треки из Яндекс.Музыки в Spotify с помощью Python

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

perenosim treki iz jandeksmuzyki v spotify s pomoshhju python f1d5e3c - 🎼 Переносим треки из Яндекс.Музыки в Spotify с помощью Python

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

perenosim treki iz jandeksmuzyki v spotify s pomoshhju python 1c70690 - 🎼 Переносим треки из Яндекс.Музыки в Spotify с помощью Python

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

perenosim treki iz jandeksmuzyki v spotify s pomoshhju python 72fa8c5 - 🎼 Переносим треки из Яндекс.Музыки в Spotify с помощью Python

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

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

Установим Selenium:

         pip install selenium     

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

         sudo apt-get install chromium-chromedriver     

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

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

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

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

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

get_music_data.py

         from selenium import webdriver from selenium.webdriver.chrome.options import Options import os import re  # функция, запускающая браузер def run_driver():     # включает возможность управления опциями браузера     chrome_options = Options()     # аргумент '--headless' запускает браузер без всплывающего окна     chrome_options.add_argument('--headless')     # аргумент '--log-level=3' скрывает логирование     chrome_options.add_argument('--log-level=3')     # запуск браузера     driver = webdriver.Chrome('chromedriver', options=chrome_options)     return driver      

Здесь:

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

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

         selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: stale element not found     

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

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

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

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

get_music_data.py

         # функция, создающая локальный html-файл def create_local_html_page(page_filename, page_source):     with open(page_filename + '.html', 'w', encoding='UTF-8') as file:         # запишем в локальный html-файл содержимое интернет-страницы ЯМ (page_source)         file.write(page_source)     

Здесь:

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

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

get_music_data.py

         # функция, открывающая локальный html-файл def get_local_html_page(yandex_username, page_filename, url):     # запускаем браузер     driver = run_driver()     # браузер переходит на страницу Яндекс.Музыки     driver.get(url)     # создаем локальную html-страницу с содержимым из страницы Яндекс.Музыки     create_local_html_page(page_filename, driver.page_source)     # путь к локальной html-странице     path_to_local_html_page = str('file://' + os.getcwd() + '/' + page_filename + '.html')     # браузер переходит на локальную html-страницу     driver.get(path_to_local_html_page)     return driver     

Здесь:

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

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

get_music_data.py

         # функция, удаляющая локальный html-файл def delete_local_html_page(page_path):     os.remove(page_path)     

Здесь:

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

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

get_music_data.py

         # функция, создающая словарь с названиями альбомов и именами исполнителей def get_albums(yandex_username):     # создаем ссылку на альбом     url = ''.join(['https://music.yandex.ru/users/', yandex_username, '/albums/'])     # создадим и перейдем на локальную страницу с альбомом из раздела «Также вам понравились эти плейлисты»     driver = get_local_html_page(yandex_username, 'album_page', url)     # прочтем массив с данными плейлистов     json = driver.execute_script('return Mu')     # создадим словарь, в который запишем название альбома и имя исполнителя     albums_for_spotify = {}     # получим данные альбомов     all_albums_ids = json['pageData']['albumIds']          

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

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

get_music_data.py

             # заполним словарь albums_for_spotify     for i in range(len(all_albums_ids)):         try:             # перейдем на страницу альбома             driver.get(''.join(['https://music.yandex.ru/album/', str(all_albums_ids[i])]))             # создадим для каждого альбома вложенный словарь             albums_for_spotify[i] = {}             # запишем во вложенный словарь название альбома             albums_for_spotify[i]['album_title'] = driver.find_element_by_xpath(                 "//h1[@class='deco-typo']").text             # запишем во вложенный словарь имя исполнителя             albums_for_spotify[i]['artist_name'] = driver.find_element_by_xpath(                 "//span[@class='d-artists']//a[@class='d-link deco-link']").text          except:             pass      # удалим локальный html-файл     delete_local_html_page('album_page.html')     # закроем браузер     driver.quit()      return albums_for_spotify      

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

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

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

         {0: {'album_title': 'The Essential Aerosmith', 'artist_name': 'Aerosmith'}, 1: {'album_title': 'Hyperion', 'artist_name': 'Gesaffelstein'}, ...       

driver.find_elements_by_xpath("//span[@class='d-artists']//a[@class='d-link deco-link']")[0].text – возвращает список, где первый элемент – имя первого исполнителя, если их несколько или единственного, если он записал трек соло.

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

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

         pip install spotipy     

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

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

perenosim treki iz jandeksmuzyki v spotify s pomoshhju python 87fa4e9 - 🎼 Переносим треки из Яндекс.Музыки в Spotify с помощью Python

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

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

perenosim treki iz jandeksmuzyki v spotify s pomoshhju python 4a82d1c - 🎼 Переносим треки из Яндекс.Музыки в Spotify с помощью Python

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

perenosim treki iz jandeksmuzyki v spotify s pomoshhju python 754438b - 🎼 Переносим треки из Яндекс.Музыки в Spotify с помощью Python

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

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

perenosim treki iz jandeksmuzyki v spotify s pomoshhju python ea4cb56 - 🎼 Переносим треки из Яндекс.Музыки в Spotify с помощью Python

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

perenosim treki iz jandeksmuzyki v spotify s pomoshhju python 334caf0 - 🎼 Переносим треки из Яндекс.Музыки в Spotify с помощью Python

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

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

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

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

transfer.py

         import spotipy from spotipy.oauth2 import SpotifyOAuth from spotipy import oauth2 from get_music_data import get_my_playlists, get_liked_playlists, get_albums   # функция для авторизации в Spotify def autorisation():     client_id = ''     client_secret = ''     # разрешения нашего приложения     scope = ('user-library-read, playlist-read-private, playlist-modify-private, playlist-modify-public, user-read-private, user-library-modify, user-library-read')     # URL, на который переадресуется браузер пользователя после получения прав доступа при получении ключа доступа     redirect_uri = 'http://localhost:8888/callback/'     sp_oauth = oauth2.SpotifyOAuth(client_id, client_secret, redirect_uri, scope=scope)     code = sp_oauth.get_auth_response(open_browser=True)     # получаем токен     token = sp_oauth.get_access_token(code, as_dict=False)     sp = spotipy.Spotify(auth=token)     # id пользователя Spotify     username = sp.current_user()['id']     return sp, username     

Здесь:

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

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

transfer.py

         # функция, получающая id альбома def get_album_id(query, sp):     # получим данные по альбому из поискового запроса в Spotify     album_id = sp.search(q=query, limit=1, type='album')     # получим id альбома     # split() – делает список, состоящий из одной строчки для метода current_user_saved_albums_add()     return album_id['albums']['items'][0]['id'].split()     

Здесь:

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

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

transfer.py

         # функция для переноса альбомов def transfer_albums(yandex_username, albums_for_spotify):     # авторизуемся в Spotify     sp, username = autorisation()     # albums_for_spotify – альбомы для переноса из Яндекс.Музыки     # содержит название трека и имя исполнитель     for i in range(len(albums_for_spotify)):         try:             # получим название альбома             album_title = albums_for_spotify[i]['album_title']             # получим имя исполнителя             artist_name = albums_for_spotify[i]['artist_name']             # сформируем поисковый запрос в Spotify             query = ' '.join([artist_name,  album_title])             # получим id альбома в Spotify             album_id = get_album_id(query, sp)             # добавим альбом в свою фонотеку             sp.current_user_saved_albums_add(album_id)          except:             pass     

Здесь:

  • 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 альбомов на ЯМ:

get_music_data.py

         # функция, получающая id плейлистов def get_my_playlists_id(yandex_username):     # создадим ссылку на плейлист     url = ''.join(['https://music.yandex.ru/users/', yandex_username, '/playlists/'])     # создадим и перейдем на локальную страницу плейлиста     driver = get_local_html_page(yandex_username, 'playlist_page', url)     # получим массив с данными плейлистов     json = driver.execute_script('return Mu')     # получим id плейлистов     my_playlists_id = json['pageData']['playlistIds']      return my_playlists_id     

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

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

get_music_data.py

         # функция, создающая словарь с названиями личных плейлистов, треков и именами исполнителей def get_my_playlists(yandex_username):     # получим id плейлистов     my_playlists_id = get_my_playlists_id(yandex_username)     # создадим словарь, в который запишем название плейлистов, треков и имена исполнителей     my_playlists_for_spotify = {}     # заполним словарь my_playlists_for_spotify     for i in range(len(my_playlists_id)):         # создадим ссылку на плейлист         my_playlist_url = ''.join(['https://music.yandex.ru/users/',                                   yandex_username, '/playlists/', str(my_playlists_id[i])])         # создадим и перейдем на локальную страницу плейлиста         driver = get_local_html_page(yandex_username, 'my_playlist', my_playlist_url)         # получим массив с данными плейлистов         json = driver.execute_script('return Mu')          # создадим словарь, в который запишем название трека и имя исполнителя         my_playlists = {}         # получим из json значение id трека и id плейлиста в формате track_id:playlist_id         all_track_ids = json['pageData']['playlist']['trackIds']         # получим название плейлиста         playlist_name = json['pageData']['playlist']['title']     

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

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

get_music_data.py

                 # заполним словарь my_playlists         for j in range(len(all_track_ids)):             # получим id трека             track_id = re.findall(r'd+(?=:)', all_track_ids[j])[0]             # перейдем на страницу трека             driver.get(''.join(['https://music.yandex.ru/track/', track_id]))             # создадим вложенный словарь для каждого плейлиста             my_playlists[j] = {}             # запишем в словарь название трека             try:                 my_playlists[j]['track_name'] = driver.find_elements_by_xpath("//span[@class='']//a[@class='d-link deco-link']")[0].text             except:                 my_playlists[j]['track_name'] = ['']             # запишем в словарь имя исполнителя             try:                 my_playlists[j]['artist_name'] = driver.find_elements_by_xpath(                 "//span[@class='d-artists']//a[@class='d-link deco-link']")[0].text             except:                 my_playlists[j]['track_name'] = ['']          # запишем в словарь название плейлиста, его треки и имена исполнителей         my_playlists_for_spotify[playlist_name] = my_playlists          # удалим локальный html-файл         delete_local_html_page('my_playlist.html')       # закроем браузер     driver.quit()      return my_playlists_for_spotify     

Здесь:

  • track_id = re.findall(r'd+(?=:)', all_track_ids[j])[0]all_track_ids имеет вид ID_трека:ID_плейлиста. Используем регулярное выражение, чтобы получить все числа до двоеточия – ID трека.

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

         {'Мне нравится': {0: {'track_name': 'Memory (From "Cats")', 'artist_name': 'London Theatre Orchestra'}, 1: {'track_name': 'All By Myself', 'artist_name': 'Céline Dion'}, ...     

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

transfer.py

         # функция, получающая id трека def get_track_id(query, sp):     # получаем данные по первому треку из поисковой выдачи Spotify     track_id = sp.search(q=query, limit=1, type='track')     # Теперь найдем id первого трека из поисковой выдачи.     # метод split() сделает список из одной строчки.eя     # Это нужно для метода playlist_add_items(), принимающего в качестве второго аргумента список.     return track_id['tracks']['items'][0]['id'].split()     

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

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

transfer.py

         # функция, переносящая плелисты def transfer_playlists(yandex_username, playlists_for_spotify):     # авторизуемся в Spotify     sp, username = autorisation()     # playlists_for_spotify – плейлисты из Яндекс Музыки (название и исполнитель)     # плейлисты берем из функций get_liked_playlists() и get_my_playlists()     # создадим плейлисты     for i in range(len(playlists_for_spotify)):         # сделаем список из ключей/названий плейлистов         playlist_name = list(playlists_for_spotify.keys())[i]         # создадим в Spotify плейлист с именем (playlist_name)         create_spotify_playlist = sp.user_playlist_create(username, playlist_name)         # получим id созданного плейлиста         new_spotify_playlist_id = create_spotify_playlist['id']         # number_of_tracks – количество треков в плейлисте playlist_name         number_of_tracks = range(len(playlists_for_spotify[playlist_name]))         new_spotify_playlist = {}     

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

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

transfer.py

                # добавим песни в плейлист Spotify         for j in number_of_tracks:             try:                 # получим имя исполнителя                 artist_name = playlists_for_spotify[playlist_name][j]['artist_name']                 # получим название трека                 track_name = playlists_for_spotify[playlist_name][j]['track_name']                 # query – поисковый запрос в Spotify, состоящий из имени исполнителя (artist_name), пробела (' ') и названия трека (track_name)                 query = ' '.join([artist_name,  track_name])                 # получим id найденного трека в Spotify                 spotify_track_id = get_track_id(query, sp)                 # добавим в словарь id трека (ключ) и id плейлиста (значение)                 new_spotify_playlist[spotify_track_id[0]] = new_spotify_playlist_id             except:                 pass          # если плейлист пустой (треки отсутствуют в каталоге Spotify), то удалить его из Spotify         if all(query == '' for query in new_spotify_playlist.values()):             sp.user_playlist_unfollow(username, new_spotify_playlist_id)             continue          # если в каталоге есть хотя бы один трек, то добавить трек(и) в плейлист Spotify         else:             for new_spotify_playlist_id, track_id in new_spotify_playlist.items():                 sp.playlist_add_items(track_id, new_spotify_playlist_id.split())     
  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 лайкнутых плейлистов, их названиями и именами пользователей, создавших плейлист.

get_music_data.py

         # функция, создающая словарь с id лайкнутых плейлистов, их названиями # и именами пользователя, создавших плейлист def get_liked_playlists_data(yandex_username):     # создадим ссылку на плейлист     url = ''.join(['https://music.yandex.ru/users/', yandex_username, '/playlists/'])     # создадим и перейдем на локальную страницу с плейлистами из раздела «Также вам понравились эти плейлисты»     driver = get_local_html_page(yandex_username, 'playlist_page', url)     # получим массив с данными плейлистов     json = driver.execute_script('return Mu')     # создадим словарь, в который запишем имя пользователя, создавшего плейлист, id и название плейлиста     liked_playlists_data = {}     # получим все данные об избранных плейлистах     bookmarked_playlists_data = json['pageData']['bookmarks']     # заполним словарь liked_playlists_data     for i in range(len(bookmarked_playlists_data)):         try:             # создадим вложенный словарь для каждого плейлиста             liked_playlists_data[i] = {}             # запишем во вложенный словарь id плейлиста             liked_playlists_data[i]['id'] = bookmarked_playlists_data[i]['kind']             # запишем во вложенный словарь имя пользователя             liked_playlists_data[i]['yandex_username'] = bookmarked_playlists_data[i]['owner']['login']             # запишем во вложенный словарь название плейлиста             liked_playlists_data[i]['playlist_title'] = bookmarked_playlists_data[i]['title']         except:             pass      # удалим локальный html-файл     delete_local_html_page('playlist_page.html')      return liked_playlists_data     

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

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

get_music_data.py

         # функция, которая переходит на страничку лайкнутых плейлистов и получает названия треков и исполнителей def get_liked_playlists(yandex_username):     # получим id плейлистов, их названия и имя пользователя, создавшего плейлист     liked_playlists_data = get_liked_playlists_data(yandex_username)     # создадим словарь, в который запишем название плейлиста, треков и имя исполнителя     liked_playlists_for_spotify = {}      for key, value in liked_playlists_data.items():         # ключ – порядковый номер плейлиста в словаре liked_playlists_data, а значения – имя пользователя и id плейлиста         # создадим ссылку на плейлист пользователя         url = ''.join(['https://music.yandex.ru/users/',                       str(value['yandex_username']), '/playlists/', str(value['id'])])         # создадим и перейдем на локальную html-страницу плейлиста         driver = get_local_html_page(yandex_username, str(key), url)         # получим массив с данными плейлистов         json = driver.execute_script('return Mu')         # создадим словарь, в который запишем треки и имя исполнителей         liked_playlists = {}         # получим из json значение id трека и id альбома в формате track_id:album_id         all_track_ids = json['pageData']['playlist']['trackIds']         # получим название плейлиста         playlist_name = json['pageData']['playlist']['title']      

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

  1. Переходим на страницу плейлиста.
  2. Получаем ID треков в формате ID_трека:ID_альбома.

get_music_data.py

                 # запишем в словарь треки и имена исполнителей         for i in range(len(all_track_ids)):             try:                 # отфильтруем только id трека                 track_id = re.findall(r'd+(?=:)', all_track_ids[i])[0]                 # перейдем на страницу трека                 driver.get(''.join(['https://music.yandex.ru/track/', track_id]))                 # создадим вложенный словарь для каждого плейлиста                 liked_playlists[i] = {}                  # получим название трека из боковой панели                 try:                     liked_playlists[i]['track_name'] = driver.find_elements_by_xpath("//span[@class='']//a[@class='d-link deco-link']")[0].text                 except:                     liked_playlists[i]['track_name'] = ['']                  # получим имя исполнителя из боковой панели                 try:                     liked_playlists[i]['artist_name'] = driver.find_elements_by_xpath(                         "//span[@class='d-artists']//a[@class='d-link deco-link']")[0].text                 except:                     liked_playlists[i]['artist_name'] = ['']              except:                 pass          # запишем в словарь название плейлиста, его треки и имена исполнителей         liked_playlists_for_spotify[playlist_name] = liked_playlists         # удалим локальный html-файл         delete_local_html_page(str(key) + '.html')          # закроем браузер         driver.quit()      return liked_playlists_for_spotify     

Здесь:

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

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

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

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

transfer.py

         def main(yandex_username):     # перенос плейлиста «Мне нравится» и личных плейлистов     #transfer_playlists(yandex_username, get_my_playlists(yandex_username))     # перенос лайкнутых плейлистов     #transfer_playlists(yandex_username, get_liked_playlists(yandex_username))     # перенос альбомов     transfer_albums(yandex_username, get_albums(yandex_username))   if __name__ == "__main__":     yandex_username = 'имя пользователя Яндекс.Музыки'     main(yandex_username)     

GitHub Весь код с выводом на экран процесса переноса доступен в репозитории yandex-music-to-spotify на GitHub. Плейлисты переносятся долго, поэтому попробуйте сначала перенести альбомы, чтобы посмотреть, как работает скрипт.

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

perenosim treki iz jandeksmuzyki v spotify s pomoshhju python 76f5e40 - 🎼 Переносим треки из Яндекс.Музыки в Spotify с помощью Python

***

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

  • запускать браузер с помощью библиотеки Selenium;
  • извлекать информацию из переменных JavaScript и из html-тегов;
  • автоматизировать процесс получения данных;
  • прокачали навык работы со словарями Python.

Материалы по теме:

— Осваиваем парсинг сайта: короткий туториал на Python

— Инструменты дата-журналиста #2: веб-скрапинг, парсинг и визуализация данных

— Веб-скрапинг по расписанию с Django и Heroku

  • 1 views
  • 0 Comment

Leave a Reply

Π’Π°Ρˆ адрСс email Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½. ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ поля ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Ρ‹ *

Π­Ρ‚ΠΎΡ‚ сайт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Akismet для Π±ΠΎΡ€ΡŒΠ±Ρ‹ со спамом. Π£Π·Π½Π°ΠΉΡ‚Π΅, ΠΊΠ°ΠΊ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ ваши Π΄Π°Π½Π½Ρ‹Π΅ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠ΅Π².

Categories 05.

Π‘Π²ΡΠ·Π°Ρ‚ΡŒΡΡ со ΠΌΠ½ΠΎΠΉ
Close