Telegram не может форматировать строчку где повторяется <

Есть такой код

a = "Apple<.3"
await bot.send_message(message.from_user.id,
                           f'Переменная a = <code>{a}</code>')

Но телеграм не может обратобать и пишет данную ошибку.

 File "C:\Program Files\Python312\Lib\site-packages\aiogram\client\session\base.py", line 120, in check_response
    raise TelegramBadRequest(method=method, message=description)
aiogram.exceptions.TelegramBadRequest: Telegram server says - Bad Request: can't parse entities: Unsupported start tag ".3</code" at byte offset 81

Ответы (2 шт):

Автор решения: Amgarak

Telegram считает символ < как начало HTML-тега, отсюда и ошибка что некорректный HTML - Unsupported start tag ".3</code" \ Неподдерживаемый начальный тег


Как вариант, сперва экранировать:

import html

a = "Apple<.3"
escape_a = html.escape(a)

Альтернатива:

a = "Apple&lt;.3"
# '<' == '&lt;' 
# '>' == '&gt;'

И не забыть добавить parse_mode='HTML'

await bot.send_message(
        message.from_user.id,
        f'Переменная a = <code>{escape_a}</code>',
        parse_mode='HTML'  
    )

введите сюда описание изображения

→ Ссылка
Автор решения: AnnaBazueva

В AIOgram есть три (четыре) режима parse_mode:

  • None (без форматирования)
  • 'HTML'
  • 'MarkdownV2'
  • 'Markdown' (не рекомендуется, устаревший)

Тестовый код:

import asyncio
from aiogram import Bot, Dispatcher, Router, types

API_TOKEN = 'YOUR_API_TOKEN_HERE'

bot = Bot(API_TOKEN)
router = Router()
dp = Dispatcher()


async def test(message: types.Message):

    a = "Apple<.3"

    try:
        await message.answer(
            f'parse_mode=None: a = {a}', parse_mode=None
            )
    except Exception as e:
        print(f"\nОшибка при parse_mode=None:\n{e}")

    try:
        await message.answer(
            f"parse_mode='HTML': a = <code>{a}</code>", parse_mode='HTML'
            )
        # Замена "<" на "&lt;"
        # await message.answer(
        #     f"parse_mode='HTML': a = <code>{a.replace('<', '&lt;')}</code>",
        #     parse_mode='HTML'
        #     )
    except Exception as e:
        print(f"\nОшибка при parse_mode=\'HTML\':\n{e}")

    try:
        await message.answer(
            f"parse_mode='MarkdownV2': a = `{a}`", parse_mode='MarkdownV2'
            )
        # Экранировать "=" и "_"
        # await message.answer(
        #     f"parse\_mode\='MarkdownV2': a \= `{a}`", parse_mode='MarkdownV2'
        #     )
    except Exception as e:
        print(f"\nОшибка при parse_mode=\'MarkdownV2\':\n{e}")

    try:
        await message.answer(
            f"parse_mode 'Markdown': a = `{a}`", parse_mode='Markdown'
            )
        # Экранировать "_"
        # await message.answer(
        #     f"parse\_mode 'Markdown': a = `{a}`", parse_mode='Markdown'
        #     )
    except Exception as e:
        print(f"\nОшибка при parse_mode=\'Markdown\':\n{e}")


async def main():
    router.message.register(test)
    dp.include_router(router)

    await dp.start_polling(bot)


if __name__ == "__main__":
    asyncio.run(main())
Telegram server says - Bad Request: Скриншот

Ошибка при parse_mode='HTML':

can't parse entities:

Unsupported start tag ".3</code" at byte offset 34

Ошибка при parse_mode='MarkdownV2':

can't parse entities:

Character '=' is reserved and must be escaped

with the preceding '\'

Ошибка при parse_mode='Markdown':

can't parse entities:

Can't find end of the entity

starting at byte offset 5

введите сюда описание изображения

Успех, только при parse_mode=None

Можете попробовать запустить с костылями (закомментированный код), но это не вариант.


Formatting

Сделайте форматирование вашего сообщения гибким и простым.

Этот инструмент работает поверх сущностей сообщений,
а не с использованием разметки HTML или Markdown.
Вы можете легко создать свое сообщение и отправить его в Telegram без необходимости
помнить четность тегов (открытие и закрытие) или экранировать пользовательский ввод.

import asyncio
from aiogram import Bot, Dispatcher, Router, types, html
from aiogram.utils.formatting import Text, Code


API_TOKEN = 'YOUR_API_TOKEN_HERE'

bot = Bot(API_TOKEN)
router = Router()
dp = Dispatcher()


async def test(message: types.Message):

    a = "Apple<.3"

    try:
        content = Text("parse_mode=None: a = ", Code(a))

        await message.answer(**content.as_kwargs())

    except Exception as e:
        print(f"\nОшибка при parse_mode=None:\n{e}")

    try:
        await message.answer(
            text=f"parse_mode='HTML': a = {html.code(html.quote(a))}",
            parse_mode='HTML'
            )

    except Exception as e:
        print(f"\nОшибка при parse_mode=\'HTML\':\n{e}")


async def main():
    router.message.register(test)
    dp.include_router(router)

    await dp.start_polling(bot)


if __name__ == "__main__":
    asyncio.run(main())
Скриншот Резюме
введите сюда описание изображения

   ПРОСТО.   

  ЛАКОНИЧНО.  

   ЭФФЕКТИВНО.   

→ Ссылка