11 March 2010

Продолжаем парсить RSS теперь уже kinozal'a используя grep, wget/curl

Decentralized networks
RSS
В моем предыдущем посте про автоматизацию загрузок новых эпизодов с RSS ленты LostFilm'а хабраюзер AmoN поднял правильный вопрос о невозможности описанным мною способом загрузки раздач, прямых ссылок на torrent файл которых в RSS ленте не содержится. В качестве примера был приведен трекер кинозал.тв. Именно решению этого вопроса посвящен сей пост ;)

Вместо введения

Перескажу вкратце суть прошлого поста. Многие популярные torrent клиенты позволяют в своих настройках задать папки слежения, анализируя которые на появление новых файлов, автоматически начинают закачки. Написанный ранее shell скрипт периодически просматривает RSS ленту трекера, выбирает интересующие нас раздачи, и загружает их torrent файлы в папку слежения.

Что в имени тебе моем?

В основе выборки и фильтрации RSS ленты прошлого способа лежал анализ регулярным выражением ссылки на torrent файл. К примеру, даже мельком взглянув на ссылку вида http://www.lostfilm.tv/download.php/2035/Lost.s06e07.rus.PROPER.LostFilm.TV.torrent
сразу же видно что это за сериал, сезон и эпизод. Однако, как верно заметил AmoN, далеко не во всех трекерах RSS ленты содержат прямые ссылки на torrent файлы что несколько затрудняет нашу задачу по автоматизации загрузок. Именно эта особенность и стала причиной сего поста :)

Нусс, приступим

Для начала, я внимательно взглянул на формат подопытной RSS ленты. И вот что увидел:

<item>
<title>The 3 Great Tenors - VA / Classic / 2002 / MP3 / 320 kbps</title>
<description>Раздел: Музыка - Буржуйская</description>
<link>http://kinozal.tv/details.php?id=546381</link>
</item>


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

Вырабатываем план

Немного поразмыслив, я выдумал следующий алгоритм:
  1. читаем RSS ленту http://kinozal.tv/rss.xml и grep'ом выбираем интересующие нас раздачи по описанию:

    curl -s http://kinozal.tv/rss.xml | grep -iA 2 'MP3'

    где "-s" — указание «вести себя тихо»,
    "-i" — регистронезависимый поиск,
    "-A 2" — указывает grep'у вместе с найденной строкой выводить еще и две следующих за ней (именно в них и содержится интересующая нас ссылка)

  2. среди выбранных раздач с помощью grep'а оставляем только ссылки:

    grep -ioe 'http.*[0-9]'

  3. открываем цикл по всем найденным ссылкам:

    for i in ... ; do ... ; done

    где на месте списка, используя «волшебные» кавычки `...` подставляем два результат наших предыдущих изысканий:

    for i in `curl -s http://kinozal.tv/rss.xml | grep -iA 2 'MP3' | grep -ioe 'http.*[0-9]'`; do ... ; done

  4. в цикле, мы для каждой из ссылок загружаем страничку и, опять же, grep'ом вытаскиваем из нее ссылку на torrent файл:

    curl -sb "uid=***; pass=***; countrys=ua" $i | grep -m 1 -ioe 'download.*\.torrent'

    где, "-b "uid=***; pass=***; countrys=ua"" — опция для задания передаваемых cookies со сведениями об авторизации,
    "-m 1" — оставляет только первую из двух прямых ссылок на torrent файл (да, на страничках описания раздач кинозала ссылка на один и тот же файл встречается дважды)

    Обращаю внимание на то, что ни пароль ни uid не не передаются в открытом виде! Их значения можно увидеть открыв окошко просмотра cookies в вашем браузере или же, к примеру, воспользоваться плагином для FireFox.

  5. загружаем torrent файлы wget'ом:

    wget -nc -qi - -B "http://kinozal.tv/" -P ~/.config/watch_dir --header "Cookie: uid=***; pass=***; countrys=ua"

    где из опций отмечу "-B "http://kinozal.tv/"" — задание префикса/домена для загрузки относительных ссылок (а именно таковыми они и являются на страницах описаний раздач кинофильма),
    и "--header "Cookie: uid=***; pass=***; countrys=ua"" — задание заголовка для GET запроса (в этот раз я захотел передать cookies именно таких способом а не через файл:) )

  6. переход на начало цикла


И что же мы имеем

А в итоге у нас получается вот такая вот "простенькая" команда:
for i in `curl -s http://kinozal.tv/rss.xml | grep -iA 2 'mp3' | grep -ioe 'http.*[0-9]'`; do curl -sb "uid=***; pass=***; countrys=ua" $i | grep -m 1 -ioe 'download.*\.torrent' | wget -nc -qi - -B "http://kinozal.tv/" -P ~/.config/watch_dir --header "Cookie: uid=***; pass=***; countrys=ua"; done

И для полного счастья, эту команду стоит прописать в cron:

*/15 * * * * наша команда > /dev/null 2>&1

За сим все, разрешите откланяться :)


UPD. В комментариях к моему предыдущему посту из этой серии было сделано несколько интересных предложений по оптимизации нагрузки на сервер:
habrahabr.ru/blogs/p2p/87042/#comment_2609116 (проверка на существования файлов)
habrahabr.ru/blogs/p2p/87042/#comment_2609714 (использование Last-Modified и ETag)

UPD2. По совету apatrushev заменил "head -1" на опцию grep "-m 1".
Tags:linuxshellgrepwgetkinozaltorrentstransmissionrtorrentcronp2p
Hubs: Decentralized networks
+25
10.6k 71
Comments 24