Урок 4. Пишем Telegram-бота для получения результатов парсинга

Опубликовано: 23 ноября в 18:09


Всем привет!

Продолжаем серию уроков по разработке парсера на Python. Сегодня мы создадим небольшого Telegram-бота для получения файлов с результатом последнего парсинга. Предположим, ваш парсер запускается раз в сутки или с другой периодичностью, и вы хотите в любой момент получить актуальную версию выгрузки.

Для написания бота в статье используется библиотека python-telegram-bot. Ссылка на официальный сайт – https://python-telegram-bot.org/.

Среда разработки – PyCharm Community Edition.

В предыдущем уроке мы отправляли по завершении парсинга файлы с результатом в чат Telegram.

Шаг 1. Подготовка

Удалим из скрипта предыдущих уроков отправку результата в Telegram и переименуем скрипт в main.py. Создадим еще один файл bot.py, в котором будем писать код нашего бота.

Установим библиотеку python-telegram-bot:

pip install python-telegram-bot
Как и в предыдущем уроке токен получим у @BotFather.

Объявим глобальную переменную TELEGRAM_TOKEN:

TELEGRAM_TOKEN = '888427890:AAFeqhoEkvoR55VKwYIyPc0X6tOVeP4uM4U'

Шаг 2. Структура бота

Рассмотри структуру бота со страницы библиотеки https://python-telegram-bot.org/:
1. Создается объект Updater, через который идет вся работа.
2. Затем обработчики пользовательских команд, сообщений.
3. Эти обработчики регистрируются в dispatcher объекта Updater.
4. Запускается опрос обновлений с серверов Telegram.

Вообще, есть два варианта получения обновлений от Telegram:
1. Периодическое опрашивание Telegram на предмет появления запросов от пользователей.
2. Вебхуки – указываем Telegram API endpoint, по которому нужно сообщить о появлении обновлений.
Сегодня мы используем первый вариант.

У нас будет две кнопки, которые отображаются после отправки команды /start:
1. «Получить JSON» для получения последней актуальной выгрузки в формате JSON.
2. «Получить XLSX» – аналогично для Excel-таблицы.

Шаг 3. Программирование

Пойдем по порядку согласно структуре. Создади объект Updater, указав наш токен. Передадим параметр use_context=True для обратной совместимости, что рекомендуется библиотекой:

updater = Updater(TELEGRAM_TOKEN, use_context=True)

Теперь напишем обработчик команды /start – мы будем отправлять текст пользователю и две кнопки для получения файлов JSON и XLSX соответственно.

def start_handler(update, context):
    text = 'Привет! Выбери, в каком формате прислать парсинг?'
    keyboard = [
        [InlineKeyboardButton(text='Получить JSON', callback_data='get_json'), ],
        [InlineKeyboardButton(text='Получить XLSX', callback_data='get_xlsx'), ],
    ]
    markup = InlineKeyboardMarkup(keyboard)
    update.message.reply_text(text=text, reply_markup=markup)

Напишем обработчики кнопок – получаем нужный файл и отправляем его в диалог вместе с датой и временем последней его модификации (используя средства операционной системы, библиотека os):

def callback_handler(update, context):
    query = update.callback_query
    query.answer()
    filenames = {
        'get_json': OUT_FILENAME,
        'get_xlsx': OUT_XLSX_FILENAME,
    }
    filename = filenames.get(query.data)
    if filename:
        modified_at = datetime.datetime.fromtimestamp(os.path.getmtime(filename)).strftime('%Y-%m-%d %H:%M:%S')
        caption = 'Результат парсинга от {}.'.format(modified_at)
        with open(filename, 'rb') as f:
            context.bot.send_document(query.message.chat.id, document=f, caption=caption)

Зарегистрируем наши обработчики:

updater.dispatcher.add_handler(CommandHandler('start', start_handler))
updater.dispatcher.add_handler(CallbackQueryHandler(callback_handler))

Опрашиваем Telegram на наличие обновлений:

updater.start_polling()
updater.idle()

Итог

Запускаем бот, пишем /start и видим две кнопки. Нажимаем любую из них, получаем файлы с результатом парсинга! К каждому файлу подписано время его последнего изменения.

На этом все, спасибо за внимание!

Полный текст исходного кода.

Если у вас возникли какие-то вопросы, можете задать их в комментариях к этой статье или под видео на YouTube. Предлагайте темы следующих уроков.

Спасибо за внимание!

Обсудить в Telegram