Архив за месяц: Октябрь 2017

Постинг в канал telegram с помощью python или бот telegram в 3 строчки

Предположим надо написать телеграмм бота, который при появлении свежей новости на сайте пишет в канал. Практическое применение для меня было в том, что на одном сайте изредка появляется важная информация, которую пропускать не хотелось, но и постоянно мониторить сайт тоже. В итоге захотелось написать максимально простой и минималистичный python скрипт, выполнющий задачу постинга в канал telegram и не использующий даже базу данных. Такая простота достигается следующим образом: по крону раз в сутки запускается программа, которая вытягивает все новости за вчерашний день. Непосредственно отправление сообщения в канал занимает 3 строчки, подробнее об этом конце, а сейчас разделим задачу на несколько логических последовательных подзадач:

  1. Отслеживание появления новости

    • 1.1 Запрос html страницы (использование бибиотеки requests)
    • 1.2 Парсинг html страницы (здесь будем использовать питон библиотеку BeautifulSoup)
    • 1.3 разбивка списка новостей на старые и новые публикации
  2. Отправка сообщения в телеграм канал

    • 2.1 Создание канала а также бота с помощью BotFather и добавление бота в администраторы канала
    • 2.2 Выбор библиотеки и её инициализация с помощью токена telegram, полученного от все того же BotFather (в нашем случае это библиотека python-telegram-bot )
    • 2.3 Отправка сообщения.
  3. Настройка обработчика cron

    • раз в сутки: «1 12 * * * /path/to/bot.py >/dev/null 2>&1″
# подключаем библиотеки
import requests
import random
from bs4 import BeautifulSoup
from datetime import date, timedelta
import telegram

# будем брать информацию за вчерашний день
yesterday = date.today() - timedelta(1)
yesterday_str = yesterday.strftime('%d.%m.%Y')

# На некоторых сайтах стоит минимальная защита и они не отдают контент без user-agent
headers = {'user-agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'}
# чтобы избежать кэширования на любом уровне, на всякий случай добавим случайно число
r = requests.get('http://здесь-название-сайта.ru/?r='+str(random.random()))

# парсинг заголовков и времени создания новости
soup = BeautifulSoup(r.text, 'html.parser')
h2s = soup.find_all('h2', class_='PostHeaderIcon-wrapper')
h2s = [x.text.strip() for x in h2s]
times = soup.find_all('div', class_='PostHeaderIcons metadata-icons')
times = [x.text.strip() for x in times]

for k, t in enumerate(times):
    if t.split()[0] == yesterday_str:  # если новость за вчера, то постим
        # Непосредственно здесь идет отправка. Инициализируем бота с помощью токена
        bot = telegram.Bot(token='123456789:AABBCCDDefgh_mnaviwuue_DP865Y')
        chat_id = '@here_some_channel_to_post'
        # тест новости
        chat_text = 'Новая новость на <a href="http://здесь-урл-сайта.ru">сайте</a>:\n {}'.format(h2s[k])
        # отправка поста в канал. Маленькая тонкость - используется HTML разметка
        bot.send_message(chat_id=chat_id, text=chat_text, parse_mode=telegram.ParseMode.HTML)

Таким вот несложным образом создан информационный telegram бот для канала. В канал можно приглашать других пользователей и они будут получать пуш-уведомления. Если сделать сухую выжимку из всего кода выше, то непосредственно отправка сообщения канал telegram займет 3 строчки:

import telegram
bot = telegram.Bot(token='123456789:AABBCCDDefgh_mnaviwuue_DP865Y')
bot.send_message(chat_id='@here_some_channel_to_post', text='some text to post')