среда, 9 декабря 2015 г.

Бекап аудиозаписей с плейлиста ВКонтакте (до 6000) средствами Python и Vk API / Хабрахабр

Бекап аудиозаписей с плейлиста ВКонтакте (до 6000) средствами Python и Vk API

Здравствуйте.

Раньше часто слушал музыку средствами «Вконтакте» (далее ВК). После перехода на Ubuntu 14.10 возникли проблемы в виде полного зависания компьютера во время прослушивания аудиозаписей через браузер Google Chrome для linux систем. В связи с этим возникла необходимость забекапить свой плейлист для прослушивания музыки в оффлайн режиме. Для этих целей решил написать маленький скрипт на языке Python, которым можно будет не только скачивать музыку с нуля, но и обновлять существующую библиотеку.

Я использовал такие модули:
  • Selenium webdriver
  • requests
  • json
  • os

Собственно, начнем.

Сначала подключаем модули:

import os  import requests  from selenium import webdriver  import json  

Далее нужно получить access_token для выполнения запросов к API и получения необходимых нам прав доступа.
Перед этим нам нужно создать и активировать свое Standalone/Desktop приложение, id которого мы будем указывать в запросе.

Схема довольно простая: Мы открываем окно браузера, переходим по ссылке, вводим данные от аккаунта, разрешаем доступ, на выходе копируем необходимые данные с url(это access_token и expires_in — срок истекания токена).

Более детально о создании приложения и авторизации можно почитать здесь.

Я использовал selenium из-за собственной лени. У этого модуля достаточно функционала для автоматизации всех вышеуказанных действий. Вы можете использовать любой другой виртуальный браузер, который вам нравится.

Собственно код с комментариями:

# Создаем объект драйвера    driver = webdriver.Firefox()    # Переходим по ссылке.  # client_id - идентификатор созданного нами приложения  # scope - права доступа  driver.get("http://api.vkontakte.ru/oauth/authorize?"             "client_id=4591034&scope=audio"             "&redirect_uri=http://api.vk.com/blank.html"             "&display=page&response_type=token")    user = "email/phone"  password = "password"    # Находим элементы формы и вводим данные для авторизации  user_input = driver.find_element_by_name("email")  user_input.send_keys(user)  password_input = driver.find_element_by_name("pass")  password_input.send_keys(password)    # Нажимаем на кнопку  submit = driver.find_element_by_id("install_allow")  submit.click()    # Получаем необходимые данные для выполнения запросов к api  current = driver.current_url  access_list = (current.split("#"))[1].split("&")  access_token = (access_list[0].split("="))[1] # acces_token  expires_in = (access_list[1].split("="))[1] # срок времени действия токена  user_id = (access_list[2].split("="))[1] # id нашей учетной записи в ВК  # Закрываем окно браузера    driver.close()  

До недавнего времени «ВК API» возвращало все данные в формате xml, что было немного неудобным. Сейчас же ответы сериализируются в json словарь с которым можно без проблем работать. Здесь нам пригодится библиотека json, а конкретнее метод loads(), который преобразовывает строку в словарь.

Дальше план действий довольно простой:
  1. Выполняем запрос и получаем в ответе список всех аудиозаписей с плейлиста учетной записи (ограничение до 6000);
  2. Преобразовываем ответ в словарь;
  3. Берем необходимую информацию со словаря (исполнитель, название трека, ссылка на трек);
  4. Скачиваем аудиозаписи в нужную директорию, называя нужными названиями, а не стандартным набором букв, в котором хранится название трека.


Первый шаг:

# Принт для дебага  print "Connecting"  # Адрес запроса  url = "https://api.vkontakte.ru/method/" \        "audio.get?uid=" + user_id +\        "&access_token=" + access_token  # Создаем листы для хранения данных  artists_list = []  titles_list = []  links_list = []  # счетчик для дебага и перехода по элементам листов  number = 0  # Читаем ответ сервера и сохраняем в переменную  page = requests.get(url)  html = page.text  

Второй шаг:

my_dict = json.loads(html) # используем loads()  


Третий шаг, думаю все понятно без комментирования:

for i in my_dict['response']:      artists_list.append(i['artist'])      titles_list.append(i['title'])      links_list.append(i['url'])      number += 1  

Четвертый и заключительный шаг:

# Создаем директорию, если она не была создана ранее    path = "downloads"    if not os.path.exists(path):      os.makedirs(path)  # Принт для дебага  print "Need to download: ", number    # Процесс скачивания файлов    for i in range(0, number):    # Путь по которому будет храниться/скачиваться конкретная аудиозапись      new_filename = path+"/"+artists_list[i] + " - " + titles_list[i] + ".mp3"      print "Downloading: ", new_filename, i  # Проверка на существующий файл      if not os.path.exists(new_filename):  # Сама загрузка файла, отсекаем из ссылки все аргументы и указываем путь куда скачивать          with open(new_filename, "wb") as out:              response = requests.get(links_list[i].split("?")[0])              out.write(response.content)    print "Download complete."  

Сейчас веду работу над самопальным плеером для прослушивания аудиозаписей с ВК (да, именно отдельный плеер, а не плагин для уже существующих популярных проигрывателей). В дальнейшем планирую написать статью, в которой будет описан процесс.

На этом все, спасибо за внимание.

UPD:
Статья немного отредактирована в соответствии с пожеланиями из комментариев.


Sent from my iPhone

Комментариев нет:

Отправить комментарий