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


Считаете, что Ubuntu недостаточно дружелюбна к новичкам?
Помогите создать новое Руководство для новичков!

Автор Тема: Парсинг и сбор тв программ Яндекса  (Прочитано 1573 раз)

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

Оффлайн Cxms

  • Автор темы
  • Активист
  • *
  • Сообщений: 407
    • Просмотр профиля
Сделал:
Get_tv_progs.sh
Код: (bash) [Выделить]
#!/bin/bash
IFS=$'\n'

# id региона (номер в ссылке на канал после "tv.yandex.ru/")
# узнать нужный id можно изменив регион на tune.yandex.ru/region
REG_ID=213

# Список каналов (ссылки на каналы и их номера см. на tv.yandex.ru)
# номер канала см. в ссылке на канал после "channels/"
CHANNELS="146
18
79
162
711
1003
743"

# Разделитель между программами каналов в файле
SEP='****************************************************************************************'

# имя временного файла для обработки программ каналов на один день
PROG_FILE=".tmp_programm"
# имя временного файла для загрузки веб-страницы прграммы передач одного канала
TMP_FILE=".tmp_web_page"

# число всех каналов
ALL_CHNLS_N=$(echo "$CHANNELS" | wc -l)

# обрабатываем список дат формата ГГГГ-ММ-ДД (сегодня, +семь дней вперед)
for DAY in $(for DN in {0..7}; do date -d "+$DN day" +"%F"; done); do
        # счетчик номера файла программы
        let PR_N+=1

        echo "Загрузка прогрммы на ${DAY}... "

        # обрабатываем список каналов
        for CHANNEL in $CHANNELS; do
                # счетчик обработанных каналов
                let CH_N+=1

                echo -e "\tКанал $CH_N из ${ALL_CHNLS_N}... "

                # формирование ссылки на программу канала
                CHANNEL_LINK="https://tv.yandex.ru/${REG_ID}/channels/${CHANNEL}?date=${DAY}&period=all-day"

                # загрузка веб-страницы прграммы передач одного канала
                wget -q -O - "$CHANNEL_LINK" | sed 's/></>\n</g' > "$TMP_FILE"

                # проверка статуса завершения загрузки веб-страницы
                [ "$?" != 0 ] && { echo "Ошибка загрузки страницы $CHANNEL_LINK"; rm "$TMP_FILE"; continue; }

                # получаем и выводим имя канала
                CHANNEL_NAME=$(grep '<h1 class="b-content__title b-content__title_page_channels">' "$TMP_FILE" \
                | grep -o ">.*<" | tr -d ">|<")
                echo -e "${SEP}\n${CHANNEL_NAME}\n" >> "$PROG_FILE"

                # получаем и сохраняем в массив названия передач
                for PER_NAME in $(grep '<div class="tv-event__title-inner">' "$TMP_FILE" | grep -o ">.*<" | tr -d ">|<")
                do PER_NAMES_AR[N]="$PER_NAME"; let N+=1
                done

                # получаем время передач и записываем в файл время и названия передач
                for PER_TIME in $(grep '<span class="tv-event__time-text">' "$TMP_FILE" | grep -o ">.*<" | tr -d ">|<")
                do echo -e "\t$PER_TIME\t${PER_NAMES_AR[NN]}" >> "$PROG_FILE"; let NN+=1
                done

                # добавляем пустую строку в конец
                echo >> "$PROG_FILE"
                # удаляем временный файл
                rm "$TMP_FILE"
                # удаляем переменные и массив
                unset N NN PER_NAMES_AR
        done
        CH_N=0
        # добавляем разделитель между программами каналов
        echo "$SEP" >> "$PROG_FILE"
        # Получаем дату формата: "День_недели_дд_мес.", и перемиеновываем файл программ каналов на день
        DATE_R=$(date -d "$DAY" +"%A_%-e_%b")
        mv "$PROG_FILE" "${PR_N}_Программа_на_${DATE_R}txt"
done

Скрипт сохраняет программы передач списка каналов в файлах с именами:
"N_Программа_на_(день_недели)_(дд)_(мес).txt"для текущего дня +на неделю вперед.
Формат программ для каналов:
**********************************
Имя_канала1

    ЧЧ:ММ   Название передачи1
    ЧЧ:ММ   Название передачи2
     ...

**********************************
Имя_канала2

    ЧЧ:ММ   Название передачи1
    ЧЧ:ММ   Название передачи2
     ...

**********************************
Запуск:
bash Get_tv_progs.sh
Размер загружаемой веб-страницы прграммы передач для одного канала 40-50 KB.
« Последнее редактирование: 10 Январь 2016, 11:07:20 от Cxms »

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6017
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Re: Парсинг тв программы Яндекса
« Ответ #1 : 07 Январь 2016, 14:44:28 »
Есть специализированные программы для парсинга html|xml с синтаксисом подобным sed. Ну или python(request + lxml2)
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн Cxms

  • Автор темы
  • Активист
  • *
  • Сообщений: 407
    • Просмотр профиля
Re: Парсинг тв программы Яндекса
« Ответ #2 : 07 Январь 2016, 14:54:15 »
Я и обычный sed с трудом понимаю..  :-[ а html|xml, python вообще не знаю. :(

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4073
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: Парсинг тв программы Яндекса
« Ответ #3 : 07 Январь 2016, 15:06:12 »
Cxms, пообъединять логическим или, а потом повырезать теги.
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

Оффлайн Heider

  • Старожил
  • *
  • Сообщений: 1269
    • Просмотр профиля
Re: Парсинг тв программы Яндекса
« Ответ #4 : 07 Январь 2016, 15:14:25 »
Я и обычный sed с трудом понимаю..  :-[ а html|xml, python вообще не знаю. :(
Без регулярных выражений (sed, perl, pyton) задача слишком сложна. Проще протратить пару вечеров на изучение хотя бы sed, чем пытаться кромсать текст другими средствами.

Оффлайн Cxms

  • Автор темы
  • Активист
  • *
  • Сообщений: 407
    • Просмотр профиля
Re: Парсинг тв программы Яндекса
« Ответ #5 : 07 Январь 2016, 15:18:54 »
alsoijw,
Зачем логическое или? непонял.
Мне бы получить хотябы время (список), делаю по аналогии:
sed -rn 's/.*Начало_тега(.*).Конец_тега*/\1/p'но после первого совпадения выдает все подряд.

Оффлайн alsoijw

  • Старожил
  • *
  • Сообщений: 4073
  • Fedora 25 GNOME 3 amd64
    • Просмотр профиля
Re: Парсинг тв программы Яндекса
« Ответ #6 : 07 Январь 2016, 15:55:30 »
Cxms, доктор сказал в морг, значит в морг :)
sed или grep(по дефолту)  будут выдавать абзац в котором что-то найдено. По этому берём grep -o. Ключ E нужен чтобы заставить его искать по регулярке. Применяется конвеер. Что имеем? Яндекс выдаёт не только что идёт по этому каналу, но и передачи канала(дубликаты). Первый grep вырезает только программу. Именно по этому в текущем виде не выводит название канала. Его нужно выводить отдельно. И убрать поиск из второго grep. Почему логическое или? Grep "пропускает" только то что соответствует регулярке. Если искать только название, то мы потеряем время. Далее я немного правлю sed чтобы цифры не прилипали к названию передачи. Далее я удаляю теги.
Недостатки:
* не выводится название канала
(решение отдельная команда)
* несколько табуляций подряд
(замена нескольких табуляций на одну и если перед этим не идёт время, то замена на перенос строки)
Черновой вариант
Код: (bash) [Выделить]
grep -oE '<div class="b-tv-channel-schedule b-tv-channel-schedule_size_l">(.*)</div>' text | grep -oE '<h1 class="b-content__title b-content__title_page_channels">(.*)<div class="b-tv-channel-content__buttons">|<span class="tv-event__time-text">[0-9]{2}:[0-9]{2}</span>|<div class="tv-event__title"><div class="tv-event__title-inner">(.*)</div></div>' | sed 's/>/>\t/g' | sed -e :a -e 's/<[^>]*>//g;/</N;//ba'
Мало видеть нам начало - надо видеть и конец. Если видишь ты создание - значит где-то есть ТВОРЕЦ
Многие жалуются: геометрия в жизни не пригодилась. Ямб от хорея им приходится отличать ежедневно?

shura1

  • Гость
Re: Парсинг тв программы Яндекса
« Ответ #7 : 07 Январь 2016, 16:15:57 »
Молодежь  ;)

lynx -dump -width 1024 'https://tv.yandex.ru/213/channels/146?period=all-day' |
grep -A1 '\[[0-9][0-9]\][0-9][0-9]:[0-9][0-9]'  |
sed 's/^ *//; s/\[[0-9][0-9]\]//g; N; s/\n/\t/'
« Последнее редактирование: 07 Январь 2016, 21:50:18 от Jshura »

 

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