@pcdesign

Чем можно находить незакрытый html тэг?

В python 2 можно было так:

import html.parser as HTMLParser
try:
    HTMLParser.HTMLParser.feed(bufer)
except HTMLParser.HTMLParseError as e:
    print(dict(msg=e.msg, pos=(e.lineno, e.offset)))


И если какой-то тег не закрыт, то выводилось такая ошибка:
malformed tag found (22, 2)
Типа, на 22 строке, офсет 2. Есть не закрытый тег.

В python 3 выкинули HTMLParseError.
И как на python3 теперь добиться такого же результата?
  • Вопрос задан
  • 142 просмотра
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
from html.parser import HTMLParser

bufer = '''<p>
    <div>hi!
</p>'''

class MyHTMLParser(HTMLParser):
    def __init__(self):
        super().__init__()
        self.open_tags = []
    
    def handle_starttag(self, tag, attrs):
        print("Start tag:", tag)
        self.open_tags.append((tag, self.getpos()))
    
    def handle_endtag(self, tag):
        print("End tag  :", tag)
        unclosed_tags = []
        # ищем, когда был открыт нужный тег
        for i in range(len(self.open_tags)-1, -1, -1):
            if self.open_tags[i][0] != tag:
                unclosed_tags.append(self.open_tags[i])
            else:
                break
        if len(unclosed_tags) == len(self.open_tags): # тег никогда и не был открыт
            print(f"Closing tag {tag} has no matching opening tag!")
        elif unclosed_tags: # тег был открыт, но он не последний
            print("Following tags are not closed properly:\n", '\n'.join(f'    {t} at line {line} pos {col+1}' for t,(line, col) in unclosed_tags))
            del self.open_tags[-len(unclosed_tags)+1:] # сбрасываем незакрытые теги
        else: # тег был открыт, и он последний - всё в порядке
            del self.open_tags[-1]
    
    def close(self):
        super().close()
        print('Processing done')

parser = MyHTMLParser()
parser.feed(bufer)
parser.close()


Вместо вывода текста можешь сразу выкидывать исключения, или накапливать сведения об ошибках, чтобы выкинуть одно исключение с полной информацией в методе close().
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы