Качалка для сервиса Яндекс.Музыка

Написал небольшой скрипт-качалку для сервиса Яндекс.Музыка.
Скрипт позволяет скачивать как отдельные композиции, так и альбомы или плейлисты целиком. Интерфейс консольный и выглядит следующим образом:
ya-downloader-ui
В процессе работы:
ya-downloader-work

Скрипт использует сторонние модули (умеет определять их отсутствие и сообщать об этом) и портированный с JavaScript на Perl алгоритм хэширования Яндекса (находится в отдельном файле YaHash.pm), он необходим для скачивания трека.

В общем пользуйтесь.

Скачать: ya-music
GitHub: yandex-music-download

Update (23.01.15): Вышло обновление. Версия на GitHub тоже была обновлена.
Update (27.01.15): Добавлен прогресс бар, исправлена ошибка скачивания, если трек был удален с Яндекса: скачать.
Update (30.01.15): Что-то часто мелочи меняться стали. На данный момент актуальная версия на GitHub.

Качалка для сервиса Яндекс.Музыка: 187 комментариев

  1. Огромное спасибо за удобный скрипт!
    в текущем варианте очень не хватает опции -u для скачивания по веб-адресу трека/альбома/плейлиста. В таком варианте собранный PAR-ом скрипт можно будет удобно прикручивать к клик-меню по ссылке в браузере (что я уже сделал для старой Оперы http://forum.ru-board.com/topic.cgi?forum=5&topic=33748&start=4860)

    Был замечен небольшой глюк скачивания некоторых альбомов-синглов, например тут https://music.yandex.ru/album/2473524 все файлы идут с одинаковыми именами и трут друг друга. Было бы полезно добавлять (к названию файла и в тэг) серый текст из названия при его наличии.
    Из мелочей также не хватает записи в тэг номера трека и жанра (он в альбоме идет рядом с годом, причем лучше парсить не русский текст, а ссылку, содержащую англ. название).

    Еще, вот такая конструкция
    binmode STDOUT, ':encoding('.TARGET_ENC.')';
    нормально работает в скрипте, но не хочет задавать кодировку при печати в STDOUT в упакованном PAR-ом exe (Cannot find encoding "cp1251"), причем, добавление use PerlIO::encoding не помогает. Однако при прямом указании кодировки binmode(STDOUT, ":encoding(cp1251)") все работает. Если сложно "красиво" подключить cp1251 для PAR, то это место лучше сделать через if else с прямым указанием кодировок.

      1. Огромное спасибо!
        Пересобрал exe (доступен по предыдущей ссылке), для него изменил в шаблонах URL_*_REGEX "music\.yandex\.ru" на "music\.yandex\.[a-z]+" т.к. оказалось, что существуют локальные версии Яндекса (качать скрипт все равно будет с .ru, но URL скушает).

        Для тех, кто будет собирать PAR-ом для винды, уточню, что в начале скрипта надо добавлять в явном виде использование модулей:
        use Win32API::File;
        use Win32::Console::ANSI;
        use Digest::MD5;
        use File::Copy;
        use File::Temp;
        use MP3::Tag;
        use JSON::PP;
        use Getopt::Long::Descriptive;
        use Term::ANSIColor;
        use LWP::UserAgent;
        use HTTP::Cookies;
        use HTML::Entities;

        1. В таком варианте получается:
          C:\Users\admin\Desktop>ya.pl -p 1018 -k ya-playlist
          [INFO] Fetching playlist info: 1018 [ya-playlist]
          [INFO] Playlist title: Топ 100: Регги
          [INFO] Tracks total: 100
          [ERROR] Can't get track list info

    1. >>При попытке скачать плейлист просто ничего не происходит.
      Потому что в ссылке на плейлист домен указан music.yandex.ua, скрипт работает для music.yandex.ru

      >>Топ 100: Регги
      Какой шрифт у консоли стоит? В свойствах окна консоли посмотреть можно, вкладка Font/Шрифт. На англоязычной Windows, например, по-умолчанию стоит Raster Fonts, которые не отображают корректно UTF-8, выбор в свойствах, например, Lucida Console решает проблему.

      >>Can't get track list info
      Не наблюдаю у себя такого на Strawberry Perl 5.22.0.1. Может быть проблема связана с https, можно проверить, достаточно после 472 строки:
      my $request = $ua->get(YANDEX_BASE.sprintf(PLAYLIST_INFO_MASK, $opt{kind}, $playlist_id));
      написать
      print $request->as_string;exit;
      и посмотреть, что скрипт выдаст. Также могу предложить поставить модуль Mozilla::CA, возможно проблема решится.

      1. >>Какой шрифт у консоли стоит?
        Сменил, отображается. Но это проблемой и не было, и в таком состоянии альбомы качает.

        >>...написать print $request->as_string;exit; и посмотреть, что скрипт выдаст.
        Написал, получил на выходе огромную простыню html кода страницы.

        Установил модуль Mozilla::CA. Переустановил перл (был Active). В результате альбомы и треки как качались, так и качаются. URL и плейлисты нет. Перед скачиванием менял домен на ru - не помогло.

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

        1. Еще могу предложить поставить Fiddler web proxy или Charles web proxy, запустить, указать в параметрах скрипта локальный прокси, попытаться скачать плейлист и скинуть мне лог. Возможно дело в редиректах.

  2. Стала появляться ошибка при скачивании альбомов с тегом -a, треки при этом скачиваются:
    Use of uninitialized value $data in substr at ya.pl line 678.

  3. Блин, действительно теперь яндекс блочит постоянное скачивание...
    Ошибка была на этом альбоме помоему 3008672

  4. У меня только 39 скачал. Кстати всё-равно скачивание на последней версии не работает постоянно, дает ~ один альбом скачать: [ERROR] Can't get track list info

  5. Яндекс вообще звери - выводят капчу, даже если просто быстро переключать треки по какому-нибудь плейлисту у них на сайте.
    У меня там вообще в несколько потоков качалось с кучей запросов к API, теперь придётся всё жестко резать в один поток - будет медленно качать.
    Что ж, достойная защита с их стороны :)

      1. Ясное дело, что можно ИИ сделать для скачивания музыки, но стоит ли оно того? Тут вопрос в соотношении затрат и выгод, получаемых с этой музыки.
        Чем больше различных ограничений и защит, тем дороже стоит делать подобные качалки. Раз Яндекс прикрутили капчу, значит для них это имеет финансовое обоснование, поэтому они тратят деньги на разработку защиты.
        deezer.com вообще шифруют содержимое самих аудиофайлов - если просто скачать трек через инструменты разработчика браузера и открыть в проигрывателе - там будет испорченный по звучанию трек. На их сайте стоит специальный flash проигрыватель, который на лету дешифрует треки и воспроизводит их. Вот до чего может дойти :)

      2. Привет! Твоя качалка замечательная была, я ради нее перл специально поставил и скачал нужные модули=) Но она перестала работать - выдает [ERROR] Can't get track list info, хотя перед этим получилось скачать несколько треков. Реально проблема в капче? Планируется что-то делать в этом направлении? Очень жалко если все заглохнет - качалок с яндекса больше не смог найти. Я бы может даже попробовал помочь если нужна помощь, правда на перле я не большой кодер - на JAVA пишу)

        1. Проблема в капче. Планирую посмотреть, как идет работа с сервисом через мобильное приложение, может там нет капчи.

        2. Спасибо!
          Но мой совет: пропишите паузу по дефолту секунд в 10-15 (с малосодержательным сообщением типа "Waiting for a track to start..."), иначе из-за наплыва любителей много и быстро покачать они вскоре еще что нибудь нехорошее придумают.

          Еще вот тут
          https://music.yandex.ru/album/25331/track/253716
          почему то жанр криво считывается (в тег прописывается conjazz а в ссылке из альбома https://music.yandex.ru/genre/modern-jazz)

          1. Добавил. Жанр берется из json-объекта с информацией о треке. А это просто адаптированные читабельные названия, которые не являются стандартом.
            Хотя в ID3v2 жанра conjazz вроде бы тоже нет по стандарту.

      1. Отдельно треки скачиваются, а вот плейлист не скачивается.
        Для этого подписка не нужна надеюсь?
        попробовал перекинуть треки на другой публчичный плейлист так же не скачивается, пишет [ERROR] Can't get track list info

        пробую через strawberry-perl-5.20.2.1-32bit-portable, через cpan установлены не достающие модули.

    1. 5.18.2, это не связано с версией. Скорее всего блокировка или что-нибудь вроде того. Можно попробовать с --debug запустить, может что-то дельное напишет.

  6. Запускаю скрипт в linux, просит доставить модули

    [email protected]:~/Downloads/ya-music# perl ya.pl
    Please, install this modules: Mozilla::CA, MP3::Tag, Getopt::Long::Descriptive

    Подскажите пожалуйста, что это за модули? и как они правильно называется?
    Искал в репо по этим словам - не нашел

    1. http://search.cpan.org/~abh/Mozilla-CA-20160104/lib/Mozilla/CA.pm
      http://search.cpan.org/~ilyaz/MP3-Tag-1.13/lib/MP3/Tag.pm
      http://search.cpan.org/~rjbs/Getopt-Long-Descriptive-0.099/lib/Getopt/Long/Descriptive.pm

      Я не знаю, как они называются в линуксовых репозиториях, тем более это может от зависеть от конкретной сборки. Через cpan скорее всего поставится.

      1. Все получилось, но есть один нюанс..
        пробую запустить скрипт примером из help
        Скачивает только 1 трек, так и должно быть?

        [email protected]:~/Downloads/ya-music# perl ya.pl -u https://music.yandex.ru/album/215688/track/1710808
        [INFO] Fetching album info: 215688
        [INFO] Album title: A Night At The Opera
        [INFO] Tracks total: 18
        [INFO] Filtering single track: 1710808 [215688]
        [INFO] Trying to fetch track: Queen - Bohemian Rhapsody (2011 Remaster)
        [OK] Temporary saved track at ./CN5Fi9tItb
        [INFO] MP3 tags added for ./CN5Fi9tItb
        [INFO] ./CN5Fi9tItb -> ./Queen - Bohemian Rhapsody (2011 Remaster).mp3
        [OK] Done!

        Попытался натравить на свой плейлист - избранное, вылетел с:
        [INFO] Fetching playlist info: 3 [****usr login***]
        [ERROR] Can't get track list info

        1. кажется разобрался,
          в первом случае была ссылка на конкретный трек
          во втором плейлист "не публичный"

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

          отличная работа!

          pss
          недостающие пакеты для linux
          Mozilla::CA
          sudo apt-get install perl-modules
          sudo cpan -i Mozilla::CA

          MP3::Tag
          sudo apt-get install libmp3-tag-perl

          Getopt::Long::Descriptive
          sudo apt-get install libgetopt-long-descriptive-perl

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

    [email protected]:/tmp/ya# perl /tmp/ya/ya.pl -u https://music.yandex.ru/users/ya.playlist/playlists/1257 --debug
    [INFO] Fetching playlist info: 1257 [ya.playlist]
    [DEBUG] main::get_playlist_tracks_info(604): Request failed
    [ERROR] Can't get track list info

    1. Могу предложить пустить трафик через локальный прокси (вроде Charles Web Debugging Proxy), который покажет, что происходит в этом месте.
      Либо самостоятельно взять и добавить на той строке print $request->as_string; и посмотреть, в чем дело.

      1. Спасибо!! отличная работа, скрипт делает свое дело
        Проблема была в LWP::Protocol::https
        недостающий пакет для linux sudo apt-get install liblwp-protocol-https-perl

        что в итоге удалось сделать:
        после добавления трека в определенный плейлист, он скачивается и загружается в папку на яндекс.диске 8-)
        все реализовано на виртуализации в Docker на дисковом хранилище Synology, скрипт запускается каждые 15 мин.

        можно ли добавить автоматическое создание папки для скачивания, если в параметрах задана несуществующая папка?

        1. Не уверен, что это нужно, могу предложить изменить соответствующий фрагмент скрипта для себя, например, следующим образом:

  8. Самая последняя версия у меня не устанавливается на Хром. Пишет нет файла манифеста. После попытки установить предыдущую и обновить её расширение таки появилось, но объясните это нормально...

    1. Песни из плейлиста скачиваются по одной штуке! Каждый раз вылетает окно с просьбой сохранить один трек, как если бы их скачивать самому по одной штуке.

    2. Никак не указать папку для сохранения заранее. Только для каждой песни отдельно. А это неудобно ведь новые окна появляются очень быстро.

    Вопрос такой - Это действительно так задумано или у меня все не так установилось?

  9. Здравствуйте!
    Проблема с последней версией:
    e:\yandex-music-download-master\src>perl ya.pl -a 3277262
    Missing right curly or square bracket at ya.pl line 299, at end of line
    syntax error at ya.pl line 299, at EOF
    Execution of ya.pl aborted due to compilation errors.

  10. Привет!

    Не качает, например, при попытке скачать плейлист получаю ошибку и всё ничего не качается(
    [INFO] Checking Yandex.Music availability
    [OK] Yandex.Music is available
    [INFO] Fetching playlist info: **** [uid-vmvnskay]
    [INFO] Playlist title: Медленные
    [INFO] Tracks total: 2
    [INFO] Trying to fetch track: Chris De Burgh - The Lady In Red (Album Version)
    [ERROR] Can't get track url
    [INFO] Waiting for 5 seconds
    [INFO] Trying to fetch track: Celine Dion - My Heart Will Go On (из фильма «Титаник»)
    [ERROR] Can't get track url
    [OK] Done!

      1. Сюда залил: https://cloud.mail.ru/public/4Jj4/Jke2CXMdZ
        Лог работы:
        [INFO] Checking Yandex.Music availability
        [OK] Yandex.Music is available
        [INFO] Fetching playlist info: **** [uid-vmvnskay]
        [INFO] Playlist title: Медленные
        [INFO] Tracks total: 2
        [INFO] Trying to fetch track: Chris De Burgh - The Lady In Red (Album Version)
        [DEBUG] main::get_track_url(480): Request failed
        [DEBUG] main::log_response(1047): Response stored at log_1459300723
        [ERROR] Can't get track url
        [INFO] Waiting for 5 seconds
        [INFO] Trying to fetch track: Celine Dion - My Heart Will Go On (из фильма «Титаник»)
        [DEBUG] main::get_track_url(480): Request failed
        [DEBUG] main::log_response(1047): Response stored at log_1459300728
        [ERROR] Can't get track url
        [OK] Done!

        1. С --mobile=0 скачивает, но быстро в капчу процесс упрется. Почему не качает через мобильное API - не знаю, на других плейлистах нормально работает, а на ваших - нет.

  11. https://music.yandex.ru/users/music.partners/playlists/1632
    почему то качает выборочно - не все треки
    В чем может быть дело?

    [email protected]:/# /tmp/music/start.sh
    [INFO] Fetching playlist info: 1632 [music.partners]
    [INFO] Playlist title: Летнее путешествие: музыка в дорогу
    [INFO] 24
    [INFO] Trying to fetch track: Jake Owen - Beachin'
    [ERROR] Can't get track url
    [INFO] Waiting for 5 seconds
    [INFO] Trying to fetch track: Bryce Vine - Sour Patch Kids
    [ERROR] Can't get track url
    [INFO] Waiting for 5 seconds
    [INFO] Trying to fetch track: George Ezra - Budapest
    [ERROR] Can't get track url
    [INFO] Waiting for 5 seconds
    [INFO] Trying to fetch track: Lyte Funkie Ones - Summer Girls
    [OK] Temporary saved track at /tmp/music/1/bcA32_5OFL
    [INFO] MP3 tags added for /tmp/music/1/bcA32_5OFL
    [INFO] /tmp/music/1/bcA32_5OFL -> /tmp/music/1/Lyte Funkie Ones - Summer Girls.mp3
    [INFO] Waiting for 5 seconds
    [INFO] Trying to fetch track: Galantis - No Money
    [ERROR] Can't get track url
    [INFO] Waiting for 5 seconds
    [INFO] Trying to fetch track: Kenny Chesney - Summertime
    [OK] Temporary saved track at /tmp/music/1/Ko589cgXZs
    [INFO] MP3 tags added for /tmp/music/1/Ko589cgXZs
    [INFO] /tmp/music/1/Ko589cgXZs -> /tmp/music/1/Kenny Chesney - Summertime.mp3
    [INFO] Waiting for 5 seconds
    [INFO] Trying to fetch track: Twenty One Pilots - Ride
    [ERROR] Can't get track url
    [INFO] Waiting for 5 seconds

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

    1. По идее да. Другое дело скрипт не пытается авторизоваться на сайте, может подписчикам доступно больше вариантов.

  13. Ошибка при переходе по ссылке на скрипт. Можно инструкцию более менее подробную для чайников? Пожалуйста

  14. C недавнего времени не качает.

    C:\Users\User\Desktop\ya-music>ya.pl -a 3328950 -t 28782912
    [INFO] Fetching track info: 28782912 [3328950]
    [ERROR] Can't get track list info

    C:\Users\User\Desktop\ya-music>

  15. Не знаю может и удобный скрипт,но переводит на англоязычный сайт. Совершенно ничего непонятно! С помощью гугл переводчикак еще более менее скачал, так и сама прога на английском. Ничего не понятно, пожалуйста переведите на норм язык)

  16. Система FreeBSD, все модули по списку установлены.
    Установлен perl 5.20.3
    perl -v
    This is perl 5, version 20, subversion 3 (v5.20.3) built for amd64-freebsd-thread-multi

    Если запускать скрипт:
    perl ya.pl -u https://.....
    то выдает:
    Use of uninitialized value $_ in substitution (s///) at ya.pl line 102.
    Use of uninitialized value $missing_modules[0] in join or string at ya.pl line 109.
    Please, install this modules:

    А если запускать:
    ./ya.pl -u https://.....
    выдает
    ./ya.pl: use: not found
    : not found
    ./ya.pl: use: not found
    : not found
    ./ya.pl: use: not found
    : not found
    ./ya.pl: use: not found
    : not found
    ./ya.pl: use: not found
    : not found
    ./ya.pl: use: not found
    : not found
    ./ya.pl: use: not found
    : not found
    : not found
    ./ya.pl: use: not found
    : not found
    ./ya.pl: use: not found
    : not found
    ./ya.pl: NL: not found
    ./ya.pl: TIMEOUT: not found
    : No such file or directorylla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0,
    : No such file or directoryik/2.1.0 (Linux; U; Android 5.0; Google Nexus 4 - 5.0.0 - API 21 - 768x1280 Build/LRX21M),
    : No such file or directorys://music.yandex.ru,
    : No such file or directorys://api.music.yandex.net,
    ./ya.pl: MD5_SALT: not found
    ./ya.pl: 19: Syntax error: "(" unexpected

    Система FreeBSD, все модули по списку установлены.
    Что не так?

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

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