Код бота (Python/aiogram): Как правильно экранировать HTML-теги или Markdown-символы при выводе имени пользователя со ссылкой на его профиль через Telegram ID?

При разработке Telegram-ботов на Python с использованием библиотеки aiogram часто возникает задача вывода имени пользователя со ссылкой на его профиль. Ссылка формируется через конструкцию `tg://user?id=USER_ID`. Однако имя пользователя может содержать специальные символы, которые нарушат разметку сообщения. Разберём оба режима форматирования.

**HTML-режим (parse_mode=’HTML’)**

В HTML-режиме опасными символами являются «, `&` и `»`. Для их экранирования в Python используется встроенная функция `html.escape()`:

python
import html
from aiogram import Bot, Dispatcher, types

async def send_mention(message: types.Message):
user = message.from_user
safe_name = html.escape(user.full_name) # экранируем имя
user_id = user.id
text = f’{safe_name}
await message.answer(text, parse_mode=’HTML’)

Функция `html.escape()` автоматически заменит `&` на `&`, « на `>`, а кавычки — на `"`. Это надёжный и рекомендуемый способ.

**MarkdownV2-режим (parse_mode=’MarkdownV2′)**

MarkdownV2 требует экранирования значительно большего числа символов: `_`, `*`, `[`, `]`, `(`, `)`, `~`, « ` «, `>`, `#`, `+`, `-`, `=`, `|`, `{`, `}`, `.`, `!`. Каждый из них нужно предварять обратным слешем «.

python
import re

def escape_md(text: str) -> str:
escape_chars = r’_*[]()~`>#+-=|{}.!’
return re.sub(r'([‘ + re.escape(escape_chars) + r’])’, r’\1′, text)

async def send_mention_md(message: types.Message):
user = message.from_user
safe_name = escape_md(user.full_name)
user_id = user.id
text = f'[{safe_name}](tg://user?id={user_id})’
await message.answer(text, parse_mode=’MarkdownV2′)

**Использование встроенных инструментов aiogram 3.x**

В aiogram 3.x появился удобный модуль `aiogram.utils.markdown`:

python
from aiogram.utils.markdown import hlink, html_decoration

async def send_mention_v3(message: types.Message):
user = message.from_user
link = hlink(user.full_name, f’tg://user?id={user.id}’)
await message.answer(link, parse_mode=’HTML’)

Функция `hlink()` автоматически экранирует текст ссылки в HTML-формате, что избавляет от необходимости вручную вызывать `html.escape()`.

**Рекомендации**

1. Предпочитайте HTML-режим — он проще и предсказуемее.
2. Никогда не вставляйте пользовательские данные в разметку без экранирования — это может привести к ошибкам парсинга или инъекциям.
3. В aiogram 3.x используйте встроенные хелперы из `aiogram.utils.markdown`.
4. Для MarkdownV2 всегда применяйте функцию экранирования ко всем пользовательским строкам, даже если они кажутся безопасными.

Соблюдение этих правил гарантирует корректный вывод имён пользователей с кликабельными ссылками на профиль в любом формате разметки.


Задайте вопрос нейросети

Не нашли ответ? Спросите ИИ — он подготовит развёрнутую статью.