Быстрый в изучении - мощный в программировании
>> Telegram ЧАТ для Python Программистов

Свободное общение и помощь советом и решением проблем с кодом! Заходите в наш TELEGRAM ЧАТ!

>> Python Форум Помощи!

Мы создали форум где отвечаем на все вопросы связанные с языком программирования Python. Ждем вас там!

>> Python Канал в Telegram

Обучающие статьи, видео и новости из мира Python. Подпишитесь на наш TELEGRAM КАНАЛ!

Делаем бекапы аудиозаписей плейлистов Вконтакте через Vk API и Python

Музыка ВК через Python

Через Вконтакте очень удобно слушать музыку. Но, бывает, что в браузере это сделать невозможно. Может банально старый компьютер тормозить. К примеру, у меня во время проигрывания в Google Chrome компьютер намертво зависал, началось это после обновления до Ubuntu 14.10. Поэтому понадобилось найти способ бекапить имеющийся плейлист, чтобы можно было случать его оффлайн. Чтобы это сделать был написан небольшой python скрипт. Он умеет не только качать музыку, а еще и обновлять имеющуюся библиотеку.

В ход пошли следующие модули:

  • os
  • json
  • requests
  • Selenium webdriver

Итак, поехали.

Для начала нужно подключить наши модули:

import os
import requests
from selenium import webdriver
import json

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

Ничего сложного: Запускаем браузер, идем по ссылочке, вводим наши данные, даем доступ, копируем нужную информацию с адреса (а именно acces_token и expres_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()

Приступаем к следующему этапу:

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

    Действие №1:

    # Принт для дебага
    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

    Действие №2:

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

    Действие №3, думаю без комментариев все ясно:

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

    Действие №4, последнее:

    # Создаем директорию, если она не была создана ранее
     
    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."

    Ну вот, все работает.

    Комментариев: 5
    1. Очень круто, я подобное писал на PHP ушло больше кода, потому что пришлось писать класс браузера, чтобы авторизоваться через скрипт и находить поля и кнопки, а здесь уже готовый модуль

    2. Роман, ну Python часто радует программистов уже готовыми плюшками. =)

    3. Python the best, fuck of all the rest!

    4. люди скиньте кто нить исходник obmeotoff@gmail.com ! у меня видает ошибку ((

      Traceback (most recent call last):

      File "vk_audio_bk.py", line 37, in

      driver.close().driver = webdriver.Firefox()

      AttributeError: 'NoneType' object has no attribute 'driver'

      зы. mac os

    5. просто driver = webdriver.Firefox()

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

    Используйте нормальные имена.

    Имя и сайт используются только при регистрации

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

    (обязательно)