Парсим codeby, пишем бота
mrOkeyДоброго времени суток, codeby.
Дело было вечером, делать было нечего, и тут вспомнил я о конкурсе на codeby. Налил себе кофейку и начал думы думать. А не помочь ли мне, немного админу канала. А помочь, решил я и вот что получилось.
Значит проблематика такая - уважаемый r1nko припечатывает статьи с форума в telegraph. А пусть это делает какой-нить бот. Берём питон, гуглим либы. Находим – pytelegrambotapi это бот-апи телеграмма, Telegraph – api для telegraph.ph. А теперь нам нужно как-то дёргать статьи. А у нашего форума – нет апи (информация для размышления).
Отсутствие апи не причина для сдачи партии, мы парни суровые, спарсим. Я использовал для этого прекрасную либу – BeautifulSoup. Не менее изящные requests и стандартный lxml для xpath. Парсить будем эту тему - https://codeby.net/forum/threads/remotewa-oxota-na-polzovatelej-whatsapp.60194/
Итак первым делом займёмся самым простым – дёрнем тему.
Шаг 1. Клацаем F12 в браузере получаем dev tools,
Шаг 2. Клацаем на «Выбрать элемент со страницы»

Шаг 3. Наводим на тему

Шаг 4. В девтулс кликаем правой клавишей на выделенном h1, идём в копировать, идём в Xpath.

Получаем нечто – «/html/body/div[2]/div[1]/div[2]/div[2]/div[2]/div/div[1]/div[2]/div[1]/div[2]/h1»
Ну собственно сам Xpath – это такой путь к html-элементу, подробнее почитать можно на вики, так же его можно и нужно оптимизировать, делать этого я, конечно, же не буду, но получится что-то такое «//div[@class=’titleBar’]/h1» ну и тему мы получаем следующим образом, разумеется до этого необходимо получить web-страницу:

Работаем дальше
Теперь получим контент. Для этого воспользуемся более простым методом:

Мы так же посмотрели через девтулс как называется класс для поста, и теперь ищем его. С этого момента начинается пляска с бубном.
Поскольку таким образом мы выбрали все посты в теме, нам нужно найти наш. Его индекс 1, нулевым идёт пост codeby. Но это только начало наших бед.
На форуме существует специфический тег на картинках, telegraph же поддерживает только явные ссылки <img>. Фиксим:

Мы проходимся по ссылкам, если видим в ссылке картинку, меняем всю ссылку html на картинку. Возвращаем готовый для дальнейшей обработки текст.
Telegraph, а вернее библиотека api используемая, мной не поддерживает html-коды кроме этих -

Разумеется в html коде они есть, избавимся от них лёгким движением регулярок.

Aside – поддерживается, но как-то криво, поэтому его тоже уберём
Всё с парсингом закончили. Переходим к боту. Бот не будет использовать web-хук, но как-нибудь я обязательно расскажу как его настроить, там всё просто. Получаем токен у BotFather, для telegraph создадим аккаунт
import telebot
from telebot import types
from telegraph import Telegraph
import CodebyParser as cp
token = '****:********'
bot = telebot.TeleBot(token)
telegraph = Telegraph()
telegraph.create_account(short_name='1337CodebyPosts')
users = {}
В users будем хранить информацию для «адекватного» общения. Расписываем /start, всё просто – Создаём клавиатуру, приветствуем юзера, помечаем, что с юзером мы поздоровались, для этого добавляем в словарь пару {message.chat.id;0}
@bot.message_handler(commands=['start'])
def bot_init(message):
keyboard = types.ReplyKeyboardMarkup(row_width=1, resize_keyboard=True)
button_parse = types.KeyboardButton(text="Спарсить статью с Codeby.net")
keyboard.add(button_parse)
bot.send_message(message.chat.id,
("Привет, я опубликую твою статью с форума. Мой хозяин сильно ленился, поэтому в статье могут быть "
+ "косяки. Потому что гладиолус. Херак херак и в продакшн"),
reply_markup=keyboard)
users[message.chat.id] = 0
Спрашиваем у юзера ссылку на статью, Смотрим общались ли мы раньше и отправляем ему ссылку уже в телеграфе. Следующим образом:
@bot.message_handler(content_types=["text"] )
def create_post(message):
if message.text == 'Спарсить статью с Codeby.net' and users[message.chat.id] == 0:
users[message.chat.id] = 1
bot.send_message(message.chat.id, 'Отправь мне, пожалуйста, ссылку на свою тему')
return
if users.get(message.chat.id) == 1:
codebyParser = cp.codebyParser(message.text)
title = codebyParser.getTitle()
content = codebyParser.getContent()
source = ('<a href={}> Источник codeby.net </a>').format(message.text)
response = telegraph.create_page(title, author_name='@webware', author_url='https://t.me/webware',
html_content=('{}{}{}<br/>{}'.format('<p>', content, '</p>',
bot.send_message(message.chat.id, response['url'])
users[message.chat.id] = 0
return
Ну и наш main
if __name__ == '__main__': bot.polling(none_stop=True)
Получаем нашу ссылку. Всё очень просто)


