Автоматизация рутины: разработка ботов на Python для мессенджеров и веба
Основы разработки ботов на Python
В мире автоматизации боты занимают особое место. Они способны выполнять рутинные задачи, общаться с пользователями и интегрироваться с внешними сервисами. Python предлагает множество библиотек для создания ботов разного назначения. В этой части рассмотрим самые популярные подходы, начиная с эффективного решения для Telegram.
Как создать базового Telegram-бота для приема и отправки сообщений?
Наиболее эффективный способ разработки Telegram-бота на Python - использование библиотеки python-telegram-bot (версия 20+). Она предоставляет высокоуровневый асинхронный API, удобные обработчики команд и сообщений, а также встроенную поддержку состояний.
Цель: быстро создать бота, который отвечает на команды и текстовые сообщения.
Случаи использования: чат-боты службы поддержки, уведомления, интерактивные опросы.
from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters
TOKEN = 'ВАШ_ТОКЕН'
async def start(update: Update, context):
await update.message.reply_text('Привет! Я бот.')
async def echo(update: Update, context):
await update.message.reply_text(update.message.text)
def main():
app = Application.builder().token(TOKEN).build()
app.add_handler(CommandHandler('start', start))
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
app.run_polling()
if __name__ == '__main__':
main()
создание ботов python (создание ботов на python)
Пошаговое пояснение:
- Импортируются классы Update, Application, обработчики команд и сообщений.
- Функция start вызывается при команде /start и отправляет приветствие.
- Функция echo повторяет любой текст, не являющийся командой.
- Приложение создается через билдер с токеном, регистрируются обработчики и запускается бесконечный опрос (polling).
Типичные проблемы и их решения:
- Бот не отвечает: проверьте правильность токена, не заблокирован ли бот, работает ли интернет.
- Ошибка NetworkError: возможно, превышен лимит запросов - увеличьте интервал или используйте async.
- Async-функции без await: все обработчики должны быть асинхронными, иначе приложение зависнет.
Как сделать асинхронного Telegram-бота с использованием aiogram?
Библиотека aiogram (версия 3) - ещё один мощный фреймворк, ориентированный на asyncio. Он предоставляет диспетчер, фильтры и машину состояний для сложных сценариев.
Цель: создание бота с поддержкой диалогов и FSM (Finite State Machine).
Случаи использования: опросники, регистрация, многошаговые формы.
from aiogram import Bot, Dispatcher, types
from aiogram.filters import Command
from aiogram.fsm.storage.memory import MemoryStorage
import asyncio
TOKEN = 'ВАШ_ТОКЕН'
bot = Bot(token=TOKEN)
storage = MemoryStorage()
dp = Dispatcher(storage=storage)
@dp.message(Command('start'))
async def start_cmd(message: types.Message):
await message.answer('Добро пожаловать!')
@dp.message()
async def echo_all(message: types.Message):
await message.answer(message.text)
async def main():
await dp.start_polling(bot)
if __name__ == '__main__':
asyncio.run(main())
автоматизация linux python (автоматизация linux с python)
Пояснение: aiogram использует декораторы для регистрации обработчиков. Dispatcher управляет маршрутизацией, storage обеспечивает хранение состояний.
- AttributeError: 'Bot' object has no attribute 'send_message': используйте await message.answer() вместо bot.send_message().
- MemoryStorage теряет данные при перезапуске: для продакшена применяйте RedisStorage.
Как реализовать Telegram-бота без сторонних библиотек, используя requests?
Можно отправлять HTTPS-запросы к Telegram Bot API напрямую через библиотеку requests. Этот подход даёт полный контроль, но требует ручной обработки обновлений (long polling или webhook).
Цель: понимание внутреннего устройства API.
Случаи использования: минималистичные боты, интеграция с другими системами без лишних зависимостей.
import requests
import time
TOKEN = 'ВАШ_ТОКЕН'
URL = f'https://api.telegram.org/bot{TOKEN}'
def get_updates(offset=None):
url = f'{URL}/getUpdates'
params = {'timeout': 30, 'offset': offset}
resp = requests.get(url, params=params)
return resp.json()['result']
def send_message(chat_id, text):
url = f'{URL}/sendMessage'
data = {'chat_id': chat_id, 'text': text}
requests.post(url, data=data)
last_update_id = 0
while True:
updates = get_updates(offset=last_update_id + 1)
for upd in updates:
message = upd.get('message')
if message and 'text' in message:
send_message(message['chat']['id'], message['text'])
last_update_id = upd['update_id']
time.sleep(1)
Пояснение: getUpdates получает новые сообщения, sendMessage отправляет ответ. Оффсет предотвращает повторную обработку.
- Получение пустого ответа: убедитесь, что бот начал диалог с пользователем.
- Блокирующий while True: улучшается добавлением обработки исключений и повторных попыток.
Как создать Discord-бота с помощью discord.py?
Discord-боты востребованы для модерации, игр и автоматизации сообществ. Библиотека discord.py (версия 2.x) предоставляет асинхронный интерфейс и слэш-команды.
Цель: управление сервером через команды.
import discord
from discord.ext import commands
TOKEN = 'ВАШ_ТОКЕН'
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix='!', intents=intents)
@bot.event
async def on_ready():
print(f'Бот {bot.user} подключился')
@bot.command()
async def ping(ctx):
await ctx.send('Pong!')
bot.run(TOKEN)
Пояснение: объявляются intents (необходимо включить в панели разработчика Discord), бот реагирует на команды с префиксом '!'. Функция on_ready вызывается после подключения.
- Intents не включены: настройте в Discord Developer Portal -> Bot -> Privileged Gateway Intents.
- Command not found: проверьте префикс и регистр.
Как автоматизировать веб-действия с помощью Selenium в качестве бота?
Когда требуется взаимодействие с динамическими веб-страницами (автопостинг, сбор данных), Selenium позволяет управлять браузером. Это не классический бот, но инструмент автоматизации.
Цель: выполнение рутинных операций в браузере.
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
driver = webdriver.Chrome()
driver.get('https://example.com/login')
driver.find_element(By.NAME, 'username').send_keys('user')
driver.find_element(By.NAME, 'password').send_keys('pass')
driver.find_element(By.TAG_NAME, 'button').click()
time.sleep(2)
print(driver.title)
driver.quit()
Пояснение: WebDriver открывает страницу, находит поля ввода, вводит данные и нажимает кнопку. time.sleep нужен для ожидания загрузки.
- NoSuchElementException: используйте WebDriverWait и expected_conditions.
- Браузер закрывается сразу: добавьте время ожидания или режим без выхода.
Расширенные примеры создания ботов
Telegram-бот с инлайн-клавиатурой и обработкой callback данных (python-telegram-bot)
Данный пример демонстрирует создание кнопок под сообщением и реакцию на нажатие.
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import Application, CommandHandler, CallbackQueryHandler
TOKEN = 'ВАШ_ТОКЕН'
async def start(update: Update, context):
keyboard = [[InlineKeyboardButton('Нажми меня', callback_data='btn1')]]
reply_markup = InlineKeyboardMarkup(keyboard)
await update.message.reply_text('Выберите действие:', reply_markup=reply_markup)
async def button_callback(update: Update, context):
query = update.callback_query
await query.answer()
if query.data == 'btn1':
await query.edit_message_text('Вы нажали кнопку!')
def main():
app = Application.builder().token(TOKEN).build()
app.add_handler(CommandHandler('start', start))
app.add_handler(CallbackQueryHandler(button_callback))
app.run_polling()
if __name__ == '__main__':
main()
Результат: при вводе /start пользователь видит сообщение с кнопкой. После нажатия кнопки сообщение заменяется на 'Вы нажали кнопку!'. В ответе от Telegram приходит callback_query, который обрабатывается отдельным обработчиком.
Discord-бот с использованием слэш-команд (discord.py 2.x)
Современные боты Discord лучше использовать слэш-команды (application commands).
import discord
from discord import app_commands
TOKEN = 'ВАШ_ТОКЕН'
intents = discord.Intents.default()
client = discord.Client(intents=intents)
tree = app_commands.CommandTree(client)
@tree.command(name='hello', description='Приветствие')
async def hello(interaction: discord.Interaction):
await interaction.response.send_message('Привет, мир!')
@client.event
async def on_ready():
await tree.sync()
print(f'Бот {client.user} готов')
client.run(TOKEN)
Результат: после синхронизации команд в Discord появится команда /hello. При её выполнении бот отвечает 'Привет, мир!'. Для синхронизации требуется одноразовый запуск, затем команды сохраняются.
Web-бот для сбора данных с пагинацией (Selenium + BeautifulSoup)
Пример автоматизации перехода по страницам и извлечения данных.
from selenium import webdriver
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup
import time
driver = webdriver.Chrome()
base_url = 'https://books.toscrape.com/catalogue/page-{}.html'
for page in range(1, 4):
driver.get(base_url.format(page))
time.sleep(2)
soup = BeautifulSoup(driver.page_source, 'html.parser')
titles = [h3.a.get('title') for h3 in soup.find_all('h3')]
print(f'Страница {page}: {titles[:3]}...')
driver.quit()
Результат (пример): Страница 1: ["A Light in the Attic", "Tipping the Velvet", "Soumission"]... Страница 2: ["Sharp Objects", "Sapiens", "The Requiem Red"]... Страница 3: ["The Dirty Little Secrets", "The Final Empire", "The Last Mile"]...
Telegram-бот с машиной состояний (aiogram FSM)
Организация диалога с пользователем: сбор имени и возраста.
from aiogram import Bot, Dispatcher, types, F
from aiogram.filters import Command, StateFilter
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
import asyncio
TOKEN = 'ВАШ_ТОКЕН'
bot = Bot(token=TOKEN)
dp = Dispatcher()
class Form(StatesGroup):
name = State()
age = State()
@dp.message(Command('start'))
async def cmd_start(message: types.Message, state: FSMContext):
await state.set_state(Form.name)
await message.answer('Введите ваше имя:')
@dp.message(Form.name)
async def process_name(message: types.Message, state: FSMContext):
await state.update_data(name=message.text)
await state.set_state(Form.age)
await message.answer('Введите ваш возраст:')
@dp.message(Form.age)
async def process_age(message: types.Message, state: FSMContext):
if not message.text.isdigit():
await message.answer('Возраст должен быть числом. Попробуйте ещё раз.')
return
data = await state.get_data()
await message.answer(f'Спасибо, {data["name"]}! Ваш возраст: {message.text}.')
await state.clear()
async def main():
await dp.start_polling(bot)
if __name__ == '__main__':
asyncio.run(main())
Результат: бот последовательно запрашивает имя и возраст. Если возраст не число, просит повторить. После завершения диалога выводит итоговое сообщение.