http://habrahabr.ru/post/247987/
Здравствуйте.
Раньше часто слушал музыку средствами «Вконтакте» (далее ВК). После перехода на Ubuntu 14.10 возникли проблемы в виде полного зависания компьютера во время прослушивания аудиозаписей через браузер Google Chrome для linux систем. В связи с этим возникла необходимость забекапить свой плейлист для прослушивания музыки в оффлайн режиме. Для этих целей решил написать маленький скрипт на языке Python, которым можно будет не только скачивать музыку с нуля, но и обновлять существующую библиотеку.
Я использовал такие модули:
- Selenium webdriver
- requests
- json
- os
Собственно, начнем.
Сначала подключаем модули:
import os
import urllib2
import urllib
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(), который преобразовывает строку в словарь.
Дальше план действий довольно простой:
- Выполняем запрос и получаем в ответе список всех аудиозаписей с плейлиста учетной записи (ограничение до 6000);
- Преобразовываем ответ в словарь;
- Берем необходимую информацию со словаря (исполнитель, название трека, ссылка на трек);
- Скачиваем аудиозаписи в нужную директорию, называя нужными названиями, а не стандартным набором букв, в котором хранится название трека.
Первый шаг:
# Принт для дебага
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."
Сейчас веду работу над самопальным плеером для прослушивания аудиозаписей с ВК (да, именно отдельный плеер, а не плагин для уже существующих популярных проигрывателей). В дальнейшем планирую написать статью, в которой будет описан процесс.
На этом все, спасибо за внимание.