Парсим codeby, пишем бота

Парсим codeby, пишем бота

mrOkey

t.me/webware

Доброго времени суток, 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)



Получаем нашу ссылку. Всё очень просто)



codeby.net

Report Page