Скачивание музыки из vk.com

от автора

После недавней шумихи вокруг аудиозаписей на сайте vk.com решил подстраховаться и скопировать всю свою коллекцию на жесткий диск. Для решения мною была написана простенькая утилита на Java. Ниже — её код c комментариями. Статья предназначена для читателей, знакомых с любым языком программирования общего назначения и умеющих компилировать и запускать написанные на нем программы.

Важное замечание: если Ваши аудиозаписи уже изъяты, то скачать их таким образом скорее всего не получится.

Подготовка

Список аудиозаписей получается через API сайта, для доступа к API нужен access token (токен доступа). Для получения токена необходимо в перейти по адресу (это стандартный способ, описанный в документации vk.com для разработчиков):

https://oauth.vk.com/authorize?client_id=3711445&scope=audio& redirect_uri=https://oauth.vk.com/blank.html&display=page&v=5.0&response_type=token

и на загрузившейся страничке разрешить доступ приложению к своим аудиозаписям, после этого вы будете перенаправлены по адресу вида:

https://oauth.vk.com/blank.html#access_token=abc&expires_in=86400&user_id=123456

вот параметр access_token нам и нужен — запомним его. Последний параметр user_id — это ваш идентификатор пользователя, тоже понадобится.

Выполнив эти действия, Вы, фактически предоставили доступ моему приложению к списку ваших аудиозаписей, но т. к. полученный при это токен мне неизвестен — то и доступа нет, для пущей безопасности можете зарегистрировать свое приложения на vk.com и использовать его app_id.

Пишем код

Итак, токен у нас есть, можем приступить к скачиванию, в двух словах схема следующая: получаем список аудиозаписей в формате JSON, распарсиваем необходимою нам информацию (название песни, имя исполнителя и собственно адрес mp3 файла) и загружаем файл, придав ему осмысленное название.

Получение списка аудиозаписей выполняется отправкой POST запроса по адресу:
(см. метод API audio.get)

        URIBuilder builder = new URIBuilder();         builder.setScheme("https").setHost("api.vk.com").setPath("/method/audio.get")                 .setParameter("oid", USER_ID) // идентификатор пользователя, полученный ранее                 .setParameter("need_user", "0")                 .setParameter("count", "2000") // число загружаемых аудиозаписей                 .setParameter("offset", "0") // смещение, необходимое для выборки определенного количества аудиозаписей                 .setParameter("access_token", ACCESS_TOKEN); // токен доступа, полученный ранее         URI uri = builder.build(); 

Отправляем запрос и обрабатываем ответ:
(для работы с HTTP запросами используем библиотеку Apache HttpClient)

        HttpClient httpclient = new DefaultHttpClient();         HttpResponse response = httpclient.execute(httpget);         HttpEntity entity = response.getEntity();         if (entity != null) {             InputStream instream = null;             try {                 instream = entity.getContent();                 String responseAsString = IOUtils.toString(instream);                 parseAndDownload(responseAsString);             } finally {                 if (instream != null)                     instream.close();             }         } 

Для парсинга JSON используем json simple, для загрузки файла — Apache Commons IO:
(важное замечание — необходимо чтобы папка в которую Вы хотите загружать файлы уже существовала)

    private static void parseAndDownload(String resp) throws IOException, ParseException {         JSONParser parser = new JSONParser();         JSONObject jsonResponse = (JSONObject) parser.parse(resp);         JSONArray mp3list = (JSONArray) jsonResponse.get("response");         for (int i=1; i<mp3list.size(); i++) {             JSONObject mp3 = (JSONObject) mp3list.get(i);             // папка должна существовать!             String pathname = "e:/vkmp3/" + fixWndowsFileName(mp3.get("artist") +mp3.get("title"));             try {                 File destination = new File(pathname + ".mp3");                 if (!destination.exists()) {                     FileUtils.copyURLToFile(new URL((String) mp3.get("url")), destination);                 }             } catch (FileNotFoundException e) {                 System.out.print("ERROR "+pathname);             }         }     } 

В названиях композиций и именах исполнителей могут содержаться символы, запрещенные к использованию в именах файлов, убираем такие символы:
(используется Apache Commons Lang)

    private static String fixWndowsFileName(String pathname) {         String[] forbiddenSymbols = new String[] {"<", ">", ":", "\"", "/", "\\", "|", "?", "*"}; // для windows         String result = pathname;         for (String forbiddenSymbol: forbiddenSymbols) {             result = StringUtils.replace(result, forbiddenSymbol, "");         }         // амперсанд в названиях передаётся как '& amp', приводим его к читаемому виду         return StringEscapeUtils.unescapeXml(result);      } 

Компилируем, запускаем — радуемся, глядя как вся онлайн коллекция аудио загружается на диск.

Заключительные замечания

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

Полный рабочий исходный код

код

Список зависимостей

  • json-simple-1.1.1.jar
  • commons-lang3-3.1.jar
  • commons-io-2.4.jar
  • httpcomponents-client-4.2.5-bin.zip (все jar файлы из архива)

ссылка на оригинал статьи http://habrahabr.ru/post/183546/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *