Форум русскоязычного сообщества Ubuntu


Следите за новостями русскоязычного сообщества Ubuntu в Twitter-ленте @ubuntu_ru_loco

Автор Тема: BASH скрипт с парсером для RSS-ленты торрент трекера  (Прочитано 4512 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
Не фанат аниме, но чтобы проверить завел ак на этом anidub.com.
Результат:
1 Вместо торрент файла теперь получает просто: "Access denied"
2 После первой успешной загрузки curl'ом страницы торрента, далее загружает ее как не от зарег. юзера, т.е без ссылок на торрент файл (видно бан).

Оффлайн BAKT

  • Автор темы
  • Участник
  • *
  • Сообщений: 112
    • Просмотр профиля
Надо же. Тут кто-то ещё отписывался! :)



1. Если вместо торрента получаете ошибку - значит что-то не так с кукисами.
2. Представленные мною скрипты, на тот момент, были 100% рабочим.  Могу только сказать, что дальнейшая модификация именно этих же скриптов крутится уже второй месяц на моём сервере и исправно поставляет мне новинки с 3х "сериальных" трекеров. Если интересно, то могу показать как они у меня сейчас выглядят.

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

PS: Да, для большинства местных - это всё детский сад. Но для меня-самоучки, у которого в жизни не было даже ни одного урока информатики в школе - это всё маленькое, но достижение
 ;D ;D ;D ;D
« Последнее редактирование: 22 Августа 2016, 09:39:42 от BAKT »

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
BAKT, В куках были uid pwd от нового акка анидуба, и ниразу торрент скачать не удалось,
на остальных торрентах скорее тоже самое. Видно что-то не хватает. Да покажи скрипты, проверю еще.

Оффлайн BAKT

  • Автор темы
  • Участник
  • *
  • Сообщений: 112
    • Просмотр профиля
get_anidub.sh

#!/bin/bash

cook_uid="dle_user_id=XXXXXX"
cook_pwd="dle_password=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
wpath=/home/crew/parsers
spath=/home/crew/parsers/torrents/anime
tor_list=${wpath}/lists/anidub.txt
q_list=${wpath}/lists/anidub_q.txt

_marklastrun() {
echo "anidub   -- $(date)" >> ${wpath}/lastrun.log
}

_checklastline() {

lastline=$(tail -c 1 ${tor_list})
  if [ "$lastline" != "" ]; then
    echo ""  >> ${tor_list}
  else
    sed -i '/^$/d' ${tor_list}
  fi
}

_getqual() {
q=$(grep "${line}" ${q_list} | awk '{print $1}')
}

_getpagelink() {
page_link=$(curl -s http://tr.anidub.com/rss.xml \
| grep -iA 2 "title" \
| grep -iA 2 "${line}" \
| grep "link" \
| grep -io "http.*.html")
}

_gettorlink() {
tor_link=$(curl -sb "${cook_uid}; ${cook_pwd}" ${page_link} \
| grep -iA 2 ${q} \
| grep -ie 'Скачать торрент' \
| grep --max-count 1 -ioE '/engine/download\.php\?id=[0-9]{1,5}' \
| tail -n 1)
}

_gettorname() {
tor_name=$(curl -sb "${cook_uid}; ${cook_pwd}" ${page_link} \
| grep -ie 'Имя файла' \
| grep -i -E "${q}" \
| grep -ioE 'title=\"[AniDub].*.torrent\"' \
| sed -r 's/(title=|[|]|\")//g' )
}

_gettorfile() {
  if [ ! -e ${spath}/${tor_name}.added ]; then
    #echo "Файла нет. Качaем..."
    curl -s --cookie "${cook_uid}; ${cook_pwd}" \
    --referer ${page_link} \
    --user-agent "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" \
    --output ${spath}/${tor_name} \
    http://tr.anidub.com${tor_link}
  else
  #echo "Такой файл уже есть. Проверяем дату..."
  find ${spath} -name "${tor_name}.added" -mtime +2 -exec rm {} \; \
    -exec curl \
      --silent \
      --cookie "${cook_uid}; ${cook_pwd}" \
      --referer ${page_link} \
      --user-agent "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0"  \
      --output ${spath}/${tor_name} \
      http://tr.anidub.com${tor_link} \;
    #-exec echo "Найден старый файлы. Заменяем..." \; \
  fi
}

_runcheck() {
echo "Адрес страницы:${page_link}"
echo "Имя торрента: ${tor_name}"
echo "Ссылка на торрент: http://anifilm.tv${tor_link}"
echo "Качество: ${q}"
echo ""
}

_getrss() {
          curl -s http://tr.anidub.com/rss.xml \
    | grep -iA 2 "title" \
    | grep -iA 2 "${line}" > /dev/null 2>&1
}


if [ $# -ne "0" ]; then
  if [[ $1 == "-chk" ]]; then

    echo -e "\n!!!Запуск в ТЕСТОВОМ режиме !!!\n"
    _checklastline

    if [ -s ${tor_list} ]; then
      while IFS= read -r line
        do
  _getrss
    if [ $? -eq "0" ]; then

      _getqual
      _getpagelink
      _gettorlink
      _gettorname
      _runcheck

    fi
done < ${tor_list}
      fi

    else
      echo "Неизвестный ключ..."
    fi
else
      _marklastrun
      _checklastline

    if [ -s ${tor_list} ]; then
      while IFS= read -r line
        do
  _getrss
    if [ $? -eq "0" ]; then

      _getqual
      _getpagelink
      _gettorlink
      _gettorname
      _gettorfile

    fi
done < ${tor_list}
      fi
fi


get_anifilm.sh

#!/bin/bash

wpath=/home/crew/parsers
spath=/home/crew/parsers/torrents/anime
tor_list="${wpath}"/lists/anifilm.txt
q_list=${wpath}/lists/anifilm_q.txt

_marklastrun() {
echo "anifilm   -- $(date)" >> "${wpath}"/lastrun.log
}
_clearoldtorrents() {
find ${spath} -mtime +5 -exec rm {} \;
}

_checklastline() {
lastline=$(tail -c 1 "${tor_list}")
  if [ "$lastline" != "" ]; then
    echo ""  >> "${tor_list}"
  else
    sed -i '/^$/d' "${tor_list}"
  fi
}

_getqual() {
q=$(grep "${line}" ${q_list} | awk '{print $1}')
}

_getpagelink() {
page_link=$(curl -s http://anifilm.tv/rss.xml \
    | sed 's/<item>/\n\n<item>/g' \
    | grep -iE "${line}" \
    | grep -ioE "<link>http:.*(a-z|\w|-)*<\/link>" \
    | sed -r 's/<[\/]?link>//g')
}
_gettorlink() {
tor_link=$(curl -s "${page_link}" \
    | grep -iA 20 "Список торрентов" \
    | grep -iA 3 -E "${q}" \
    | grep -ioE "\/releases/download-torrent/[0-9]{1,4}")
}
_gettorname() {
tor_name=$(curl -s "${page_link}" \
    | grep -m 1 "Аниме" \
    | grep -ioE "Аниме [a-zA-Z].* \/ " \
    | sed -r 's/(Аниме | \/ |:|,|\.|\?|\!)//g' \
    | sed 's/ /_/g')

full_name=AniFilm_"${tor_name}".torrent
}

_gettorfile() {
if [ ! -e "${spath}"/"${full_name}".added ]; then
    #echo "Файла нет. Качем..."
    curl -s http://anifilm.tv"${tor_link}" -o "${spath}"/"${full_name}"
else
    #echo "Такой файл уже есть. Проверяем дату..."
    find ${spath}/ -name ${full_name}.added -mtime +2 -exec rm {} \; \
    #-exec echo "Найден старый файлы. Заменяем..." \; \
    -exec curl -s http://anifilm.tv"${tor_link}" -o "${spath}"/"${full_name}" \;
fi

}
_runcheck() {
echo "Адрес страницы:${page_link}"
echo "Имя торрента: ${full_name}"
echo "Ссылка на торрент: http://anifilm.tv${tor_link}"
echo ""
}

_getrss() {
curl -s http://anifilm.tv/rss.xml \
  | sed 's/<\/item>/<\/item>\n\n/g' \
  | grep -iE "${line}" > /dev/null 2>&1
}

if [ $# -ne "0" ]; then
  if [[ $1 == "-chk" ]]; then

    echo -e "\n!!!Запуск в ТЕСТОВОМ режиме !!!\n"
    _checklastline

    if [ -s "${tor_list}" ]; then
      while IFS= read -r line
do

  _getrss

    if [ $? -eq "0" ]; then

              _getqual
              _getpagelink
              _gettorlink
              _gettorname
              _runcheck

    fi
done < "${tor_list}"
    fi
  else
    echo "Неизвестный ключ..."
  fi

else

  _marklastrun
  _checklastline

  if [ -s "${tor_list}" ]; then
     while IFS= read -r line
      do

  _getrss

  if [ $? -eq "0" ]; then

    _getqual
    _getpagelink
    _gettorlink
    _gettorname
    _gettorfile

  fi
      done < "${tor_list}"
  fi
fi

get_newstudio.sh

#!/bin/bash

###########################################################
## Переменные

wpath=/home/crew/parsers
spath=/home/crew/parsers/torrents
tor_list=${wpath}/lists/newstudio.txt
cookies='Cookie: b=b; bb_data=a%3A3%3A%7B....s%181Ru9S7%22%3B%7D; bb_t=a%3A3%3A%7B....69113791%3B%7D'
q_list=${wpath}/lists/newstudio_q.txt

_tmp=$(mktemp tmp.XXXXXXX --tmpdir=/tmp 2>/dev/null) || tmpfile=/tmp/test$$
trap 'rm -f ${_tmp}' 0 1 2 5 15

############################################################

_checklastline() {
lastline=$(tail -c 1 ${tor_list})
  if [ "$lastline" != "" ]; then
    echo ""  >> ${tor_list}
  else
    sed -i '/^$/d' ${tor_list}
  fi
}

_marklastrun() {
echo "newstudio      --    $(date)" >> ${wpath}/lastrun.log
}

_getqual() {
q=$(grep "${line}" ${q_list} | awk '{print $1}')
}

_gettorname() {
tor_name=$(curl -s -H "${cookies}" "${page_link}" \
    | grep -io -E ".*\.torrent" \
    | sed 's/^\s*//g')
}

_gettorlink() {
tor_link=$(curl -s -H "${cookies}" "${page_link}" \
    | grep -io -E "download.php.*[0-9]{1,5}")
}

_getrss() {
curl --silent http://newstudio.tv/rss.php \
  | grep -iA 5  "${line}" \
  | grep -iA 6 -E ".*title.*${q}" \
  | grep -io -E "<link>.*</link>" \
  | sed -r 's/<[\/]?link>//g' > ${_tmp}
}

_gettorrfile() {
if [ ! -e ${spath}/${tor_name}.added ]; then
  #echo "Файла нет. Качем..."
  curl -s -H "${cookies}" http://newstudio.tv/${tor_link} -o ${spath}/${tor_name}
  sleep 3
else
  #echo "Такой файл уже есть. Проверяем дату..."
  find ${spath} -name "${tor_name}.added" -mtime +2 \
    -exec rm {} \; \
    -exec curl -s --header "${cookies}" http://newstudio.tv/${tor_link} -o ${spath}/${tor_name} \;
fi
}

_runcheck() {
echo "Адрес страницы:${page_link}"
echo "Имя торрента: ${tor_name}"
echo "Ссылка на торрент: http://newstudio.tv/${tor_link}"
echo "Качество: ${q}"
echo ""
}


if [ $# -ne "0" ]; then
  if [[ $1 == "-chk" ]]; then

    echo -e "\n!!!Запуск в ТЕСТОВОМ режиме !!!\n"
    _checklastline

    if [ -s ${tor_list} ]; then
      while IFS= read -r line; do
  _getqual
  _getrss

  for page_link in $(cat ${_tmp}); do
    _getqual
        _gettorname
    _gettorlink

    _runcheck
  done
      done < ${tor_list}
    fi
  else
    echo "Неизвестный ключ..."
  fi
else
    _checklastline

    if [ -s ${tor_list} ]; then
      while IFS= read -r line; do
  _getqual
  _getrss

  for page_link in $(cat ${_tmp}); do
    _gettorname
    _gettorlink
 
    _gettorrfile
  done
      done < ${tor_list}
    fi
fi


Ну и как пример списки закачки:

anidub.txt

С нуля: Пособие по выживанию в альтернативном мире
.взлом
Код Квалидеи

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

anidub_q.txt

720 С нуля: Пособие по выживанию в альтернативном мире
_ .взлом
720 Код Квалидеи

PS: Кстати, самый большой геммор был с подбором правильных кук для newstudio. Уж больно у них всё кулаком через..... сделано. Мне с этим помог вот этот плагинчик для FF.

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
Торренты с новым акком стали качатся.

В твоих скриптах для каждого цикла/переменной одни и теже страницы качаются по хз сколько раз, и нагорожено всего.

Оффлайн BAKT

  • Автор темы
  • Участник
  • *
  • Сообщений: 112
    • Просмотр профиля
В твоих скриптах для каждого цикла/переменной одни и теже страницы качаются по хз сколько раз, и нагорожено всего.

А можно поконкретнее?

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
Например для каждой строки списка в цикле - rss страница, страница торрента качается по 2 раза.
Списки: в первый файл писать названия, во второй- качества и названия, - что за бред? (без обид). Все легко делается одним списком.

Оффлайн BAKT

  • Автор темы
  • Участник
  • *
  • Сообщений: 112
    • Просмотр профиля
Например для каждой строки списка в цикле - rss страница, страница торрента качается по 2 раза.
Была у меня идея сохранять временно страницу и потом её парсить. Пока руки не дошли ибо был в отпуске :)

Списки: в первый файл писать названия, во второй- качества и названия, - что за бред? (без обид). Все легко делается одним списком.

Можешь показать как лучше - покажи. Я повторяю - я 100% самоучка. Возможно где-то у меня "хромает" логика, где-то не хватает знаний, а где-то я вообще не в курсе что можно сделать "вот так, а не вот так". У меня была задача: читать из списка названия сериалов - я нашёл как это сделать. Была задача, как-то сопоставить название сериала и нужное его качество - сделал и это. Да, скорее всего это костыль на костыле. Но ткните мне пальцем в того, кто сразу сел и начал кодить как бог.

Можешь поделиться опытом - я буду только рад.

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
Цитировать
сохранять временно страницу и потом её парсить
Это и не нужно, сохранять страницу можно прямо в переменную:
WEB_PAGE="$(curl http://site.com)"и потом выводить для обработки:
RESULT="$(echo "$WEB_PAGE" | grep 'pattern')"
Синтаксис:
1. Переменные в арументах команд например пути нужно оковычивать - "$PATH_TO_DIR",
  т.к наличие пробела или некоторых спец. символов вызовет ошибки.
2. Не нужно без необходимости заключать имена переменных в фигурные скобки.

разбор списка:
Код: (bash) [Выделить]
while read LINE
do
TORR_QUAL="${LINE%% *}"
TORR_NAME="${LINE#* }"


done < "$TORR_LIST"

Нет смысла в двух переменных cook_uid и cook_pwd, одной:
COOKIES='dle_user_id=XXXXXX; dle_password=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
и юзер агент вывести:
USR_AG='Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0'
_checklastline() {
lastline=$(tail -c 1 ${tor_list})
  if [ "$lastline" != "" ]; then
    echo ""  >> ${tor_list}
  else
    sed -i '/^$/d' ${tor_list}
  fi
}
это что и зачем?

Так списки ты как собираеш?

Оффлайн BAKT

  • Автор темы
  • Участник
  • *
  • Сообщений: 112
    • Просмотр профиля
Это и не нужно, сохранять страницу можно прямо в переменную:

Ну вот, как я уже и говорил - некоторые вещи мне даже в голову не приходят :)
Спасибо за наводку.

Синтаксис:
1. Переменные в арументах команд например пути нужно оковычивать - "$PATH_TO_DIR",
  т.к наличие пробела или некоторых спец. символов вызовет ошибки.
Обычно, если в выводе возможны пробелы или любые спец символы - я так и делаю.

2. Не нужно без необходимости заключать имена переменных в фигурные скобки.
Я не в курсе - это на что-то влияет, помимо того, что указанная переменная без фигурных скобок может быть не всегда "опознана"? Я имею в виду вот это:
var=123
echo $var_456
echo ${var}_456

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

разбор списка:
Код: (bash) [Выделить]
while read LINE
do
TORR_QUAL="${LINE%% *}"
TORR_NAME="${LINE#* }"


done < "$TORR_LIST"
Спасибо. Но что это за %% и т.д.? Попытался найти сам, но что в яндексе, что в гугле мало шансов найти что-то по запросу %% или #* :(

Нет смысла в двух переменных cook_uid и cook_pwd, одной:
COOKIES='dle_user_id=XXXXXX; dle_password=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
и юзер агент вывести:
USR_AG='Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0'

Тут - да, для удобства давно уже нужно было переделать.

_checklastline() {
lastline=$(tail -c 1 ${tor_list})
  if [ "$lastline" != "" ]; then
    echo ""  >> ${tor_list}
  else
    sed -i '/^$/d' ${tor_list}
  fi
}
это что и зачем?
Так списки ты как собираеш?

Списки просто руками забиваю. Когда писал скрипты, то наткнулся на ошибку, что если в списке нет закрывающей пустой строки или их больше одной, то при работе скрипта почему-то вываливаются ошибки. Отсюда и родился этот костыль - если при редактировании списка я забыл добавить строку - он добавляет, если добавил лишнюю - он убирает все кроме одной.

PS: Спасибо за то, что тратишь на меня своё время.

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
Цитировать
Спасибо. Но что это за %% и т.д.?
- Удаление части строки.
"${LINE%% *}"Удалить с конца строки все до последнего пробела.

"${LINE#* }"Удалить с начала строки все до первого пробела.

% - первое вхождение с конца
%% - последнее вхождение с конца

# - первое вхождение с начала
## - последнее вхождение с начала

Читать:
LESS=+/"Parameter Expansion" man --pager=less bashhttp://www.opennet.ru/docs/RUS/bash_scripting_guide/x4171.html

Цитировать
наткнулся на ошибку, что если в списке нет закрывающей пустой строки или их больше одной, то при работе скрипта почему-то вываливаются ошибки.
Понятно, вот:
sed -i '$s/$/\n/; /^ *$/d' "$LIST_FILE"(добавляет пустую строку в конец, потом удаляет все пустые строки или только с пробелами)

Цитировать
Списки просто руками забиваю.
А почему именно названия торрентов а не ссылки на их страницы?


Пользователь добавил сообщение 24 Августа 2016, 11:27:55:
Цитировать
_gettorfile() {
  if [ ! -e ${spath}/${tor_name}.added ]; then
    #echo "Файла нет. Качaем..."
    curl -s --cookie "${cook_uid}; ${cook_pwd}" \
    --referer ${page_link} \
    --user-agent "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" \
    --output ${spath}/${tor_name} \
    http://tr.anidub.com${tor_link}
  else
  #echo "Такой файл уже есть. Проверяем дату..."
  find ${spath} -name "${tor_name}.added" -mtime +2 -exec rm {} \; \
    -exec curl \
      --silent \
      --cookie "${cook_uid}; ${cook_pwd}" \
      --referer ${page_link} \
      --user-agent "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0"  \
      --output ${spath}/${tor_name} \
      http://tr.anidub.com${tor_link} \;
    #-exec echo "Найден старый файлы. Заменяем..." \; \
  fi
}

_gettorfile() {
[ "$(find "$spath" -type f -name "${tor_name}.added" -mtime -2)" ] && return
rm -f "$spath/$tor_name"
curl -s -A "$USR_AG" -b "$COOKIES" -e ${page_link} \
             -o "$spath/$tor_name" http://tr.anidub.com${tor_link}
}
« Последнее редактирование: 24 Августа 2016, 11:27:55 от renzrv »

Оффлайн BAKT

  • Автор темы
  • Участник
  • *
  • Сообщений: 112
    • Просмотр профиля
Сори, работа навалилась, так что не ответил сразу.
Читать:

Шикарно! Даже и не знал о таком.

(добавляет пустую строку в конец, потом удаляет все пустые строки или только с пробелами)
Спасибо, исправлю.

А почему именно названия торрентов а не ссылки на их страницы?

Изначально первый скрипт писался под трекер newstudio. А там каждая серия в каждом качестве выкладывается отдельной темой\страницей. Изврат, но местные админы давно забили на пользователей и на их просьбы. Отсюда и пошла идея парсить саму ленту по названиям и по качеству, а оттуда уже брать ссылку на страницу и т.д.

Для анимешных трекеров уже писал после, по аналогии с первым.

_gettorfile() {
...

Тоже сейчас попробую, спасибо.

 

Страница сгенерирована за 0.041 секунд. Запросов: 25.