Выкачиваем музыку с контакта. Geek way

в 20:00, , рубрики: jquery, Вконтакте, музыка, Песочница, метки: , ,

Все началось с того, что мне понравилась одна группа, где регулярно выкладывали музыку. Но так как музыку я слушаю в основном с плеера, возник вопрос о скачивании песен к себе на ПК. Хотелось сделать довольно таки большой плейлист и выбросить не понравившееся. По одной песне качать- это мазохизм. Всяким приблудам из сети не доверяю. Как я это сделал?
Начал я с беглого осмотра разметки вКонтактовской страницы. Сразу стало видно, что ссылка на песню хранится в открытом виде как value скрытого инпута, и соответствует маске http ://cs*.userapi.com/*/audio/*.mp3,*.
Быстренько состряпав jQuery запрос в консоль я… Ничего не получил, т.к. вКонтакте моя любимая библиотека не используется. Ну не беда, через ту же консоль подключаем jQuery к странице при помощи вот такого трюка:

function addJQuery(callback) {
  var script = document.createElement("script");
  script.setAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js");
  script.addEventListener('load', function() {
    var script = document.createElement("script");
    script.textContent = "(" + callback.toString() + ")();";
    document.body.appendChild(script);
  }, false);
  document.body.appendChild(script);
}

Теперь можно и делом занятся. Посмотрев все скрытые поля при помощи селектора input:hidden я увидел, что те из них содержат искомую ссылку имеют id соответствующий маске audio_info*. Немного улучшим селектор. input:hidden[id*='audio'] получает только нужные нам инпуты.
Здесь можно было бы остановится, и просто получить ссылки на все аудио примерно вот так:
$('input:hidden[id*="audio"]').each(function () {
url=$(this).attr('value').split(',')[0];
console.log("wget "+url);
});
, скормить их wget-y, и получить на выходе… Мешанину в именах файлов, т.к. не у всех песен есть idv3 теги, а название файла после скачивания состоит из символов a..z и 0..9 без намека на исполнителя или название трека. Воощем, просто айди файла на сервере. Поэтому продолжим.
Ищем неподалеку от нашего инпута информацию о исполнителе и названии композиции и приходим к выводу, что можно сделать так:

$('input:hidden[id*="audio"]').each(function () { 
url=$(this).attr('value').split(',')[0];
author=$(this).parent().parent().parent().find('b').find('a[href*="search"]').html();
song=$(this).parent().parent().parent().find('span[id*="title"]').html();
console.log('wget -O "'+author+'-'+song+'.mp3" '+url);
});

Осталось скопировать вывод консоли, убрать мусор (если есть) из файла, и запустить то, что получилось как исполняемый скрипт.
Работает отлично, мой уже скачал около 2 Гб ~ 126 песен. В один поток конечно, но я никуда не спешу. Всем, кто дочитал сюда — спасибо :)

Автор: Xazzzi

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js