하얀설표 블로그




해결)can\'t parse entities: Unsupported start tag "{tag name}" at byte offset {index}





( 수정됨)


에러 예시

다음과 같이 parse_mode를 html로 설정하고 html 태그가 섞인 메세지 텍스트를 전송할 때 발생하는 에러이다.

에러예시

import telepot
token = {텔레그램 봇 api 토큰}
id = {메세지 수신자 chat id}
text = '텔레그램봇 메세지 보내기<br>메세지\n보내기'
bot = telepot.Bot(token)
bot.sendMessage(
    chat_id=id,
    text=text,
    parse_mode='html',
)

>> Traceback (most recent call last):
  File "c:\seolpyo\example.py", line 6, in <module>
    bot.sendMessage(
  File "C:\seolpyo\Lib\site-packages\telepot\__init__.py", line 513, in sendMessage
    return self._api_request('sendMessage', _rectify(p))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\seolpyo\Lib\site-packages\telepot\__init__.py", line 491, in _api_request
    return api.request((self._token, method, params, files), **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\seolpyo\Lib\site-packages\telepot\api.py", line 155, in request
    return _parse(r)
           ^^^^^^^^^
  File "C:\seolpyo\Lib\site-packages\telepot\api.py", line 150, in _parse
    raise exception.TelegramError(description, error_code, data)
telepot.exception.TelegramError: ('Bad Request: can\'t parse entities: Unsupported start tag "br" at byte offset 35', 400, {'ok': False, 'error_code': 400, 'description': 'Bad Request: can\'t parse entities: Unsupported start tag "br" at byte 
offset 35'})

해결방법

parse_mode를 None으로 설정하거나, 텔레그램봇 api에서 사용 가능한 html 태그만을 전달한다.

설명

텔레그램봇은 parse_mode로 html과 markdown을 허용하고 있다.
단, 허용한다고 해서 웹페이지에서 사용하는 것과 같이 모든 html 태그를 허용하는 것은 아니다.

이 문제 역시 허용되지 않는 html 태그를 메세지 텍스트에 포함한 것이 문제였으며, 가장 간단한 해결방법은 parse_mode를 None으로 설정하여 메세지를 html이 아닌 일반 텍스트로 전달하도록 하는 것이다.
그러나 만약 html로 번역된 메세지를 전달하고 싶다면 텔레그램에서 허용하지 않는 태그는 메세지 텍스트에서 제거하거나, unescape한 다음 전달해야 한다.

텔레그램 bot api에서 허용하는 html 태그들은 이 링크에서 확인할 수 있다.
예시코드에서 문제가 된 태그는 br 태그였다.

텔레그램에서 허용하는 태그가 아닌 태그들을 unescape하는 코드는 다음과 같이 작성할 수 있으며, 코드 실행시 다음과 같은 메세지가 텔레그램으로 전송된다.

텔레그램봇 메세지 보내기<br/>메세지
보내기

예시코드

import html
import bs4
import telepot
def convert_by_seolpyo(text: str):
    soup = bs4.BeautifulSoup(text, 'html.parser')
    text_by_seolpyo = ''
    for i in soup:
        i: bs4.element.NavigableString|bs4.element.Tag
        if i.name in ['b', 'strong', 'i', 'em', 'u', 'ins', 's', 'strike', 'del', 'span', 'tg-spoiler', 'a', 'tg-emoji', 'code', 'pre']:
            text_by_seolpyo += str(i)
        else:
            text_by_seolpyo += html.escape(str(i))
    return text_by_seolpyo
token = {텔레그램 봇 api 토큰}
id = {메세지 수신자 chat id}
text = '텔레그램봇 메세지 보내기<br>메세지\n보내기'
bot = telepot.Bot(token)
bot.sendMessage(
    chat_id=id,
    text=convert_by_seolpyo(text),
    parse_mode='html',
)


공감 : 0







white.seolpyo.com