Понятно, что «жертвой» сегодняшнего эксперимента будет
Цель — написать
Немного поизучав
Можно приступать к написанию скрипта. Для запросов к серверу я буду использовать
Для начала запишем
В переменных
Получим кусок HTML. Информация о песне расположена в строках вида
Зная
Ссылка на скачивание песни выглядит так:
Осталось всё это совместить в один скрипт. Пусть он будет «постранично» искать песни и выводить информацию только о тех, чей bitrate совпадает с наперёд заданным.
Пробуем найти что-нибудь про хабрахабр:
z-music.org. На этом сайте есть возможность найти песню, послушать и скачать её.Цель — написать
bash скрипт для поиска музыки, используя «джентльменский набор» sed, awk и grep. Ну и плюс немного curl или wget по вкусу.Немного поизучав
z-music.org, становится ясно, что:- Поиск расположен по адресу
z-music.org/search/. В качестве GET параметров можно передать текст запросаq, тип запроса (AJAX)actionи номер страницы результата поискаpage - Узнать bitrate песни можно отправив POST запрос на
z-music.org/bitrate/с данными"id=<SONG_ID>" - Прямая ссылка на скачивание песни выглядит как
m1.z-music.org/t/<SONG_ID>_<HASH>.<HASH>нашёлся в скрипте по адресуz-music.org/theme/new/js/lang.js
Можно приступать к написанию скрипта. Для запросов к серверу я буду использовать
curl, но ничего не мешает использовать wget. Вместо curl -s будет wget -q -O -, а вместо curl -F будет wget --post-dataДля начала запишем
<HASH> в переменную hsh:hsh=$(curl -s http://z-music.org/theme/new/js/lang.js | sed -n 's/^var hsh="\([^"]*\)";$/\1/p')
В переменных
$query и $page будут лежать текст запроса и номер страницы результата. Отправим запрос на сервер:curl -s "http://z-music.org/search/?page=$page&action=ajax&q=$query"
Получим кусок HTML. Информация о песне расположена в строках вида
<a class="info" data-aid="SONG_ID"...>SONG_NAME</a>. Получим <SONG_ID> и <SONG_NAME>, разделённые табуляцией:sed -n 's/^\s*<a class="info" data-aid="\([^"]*\)"[^>]*>\([^<]*\)<\/a>\s*$/\1\t\2/p'
Зная
<SONG_ID> можно отправить запрос на bitrate. В ответ придёт JSON. Для того, чтобы вытащить само значение bitrate используем утилиту cut. Для разнообразия.curl -sF "id=$songid" http://z-music.org/bitrate/ | cut -d'"' -f8
Ссылка на скачивание песни выглядит так:
m1.z-music.org/t/${songid}_${hsh}/Осталось всё это совместить в один скрипт. Пусть он будет «постранично» искать песни и выводить информацию только о тех, чей bitrate совпадает с наперёд заданным.
#!/bin/bash case $# in 1) query=$1 bitrate=320 ;; 2) query=$1 bitrate=$2 ;; *) echo -e 'Usage:\n\tzmusic "song name"\nor:\n\tzmusic "song name" 256\nwhere 256 is bitrate' exit ;; esac hsh=$(curl -s http://z-music.org/theme/new/js/lang.js | sed -n 's/^var hsh="\([^"]*\)";$/\1/p') # infinite loop incrementing search page for (( page=1; page>0; page++ )) do result=$( \ curl -s "http://z-music.org/search/?page=$page&action=ajax&q=$query" | \ sed -n 's/^\s*<a class="info" data-aid="\([^"]*\)"[^>]*>\([^<]*\)<\/a>\s*$/\1\t\2/p' | \ awk -v hsh=$hsh -F"\t" ' \ { \ system("curl -sF \"id=" $1 "\" http://z-music.org/bitrate/ | cut -d\"\\\"\" -f8"); \ print "http://m1.z-music.org/t/" $1 "_" hsh "/"; \ print $2 "\n"; \ }') # stop the script if nothing found on this page if [ -z "$result" ]; then exit; fi # output songs with $bitrate only while read -r res; do echo -e $res; done <<< "$result" | grep -A2 "$bitrate" echo -e "-- end of page $page --\n" done
Пробуем найти что-нибудь про хабрахабр:
$ zmusic "хабр" "256\|320" 320 http://m1.z-music.org/t/-3ev4fnuc23h_2b49895762/ Хабр - Наркоманская песня -- 320 http://m1.z-music.org/t/-3ev4fnubytf_2b49895762/ ХаБр - Недомассаракш -- 320 http://m1.z-music.org/t/-3ev4fnuc1d3_2b49895762/ ХаБр - Путешествие [Ежи и Петруччо cover] -- 320 http://m1.z-music.org/t/-3ev4fntmcfl_2b49895762/ ХаБр - Не поедете на лифте (new single) -- end of page 1 --
