如何让html.parser.HTMLParser正确处理无结尾斜杠的自闭合标签
处理html.parser.HTMLParser对无斜杠自闭合标签的解析问题
默认情况下,html.parser.HTMLParser无法正确处理未以斜杠/结尾的自闭合标签。例如它能正常解析<img src="asfd"/>,但会错误地将<img src="asdf">视为非自闭合标签,导致后续元素的深度计算(如示例中的缩进)出现错误。
示例代码
from html.parser import HTMLParser class MyHTMLParser(HTMLParser): def __init__(self): super().__init__() self.depth = 0 def handle_starttag(self, tag, attrs): print('|'*self.depth + tag) self.depth += 1 def handle_endtag(self, tag): self.depth -= 1 html_content = """ <html> <head> <title>test</title> </head> <body> <div> <img src="http://closed.example.com" /> <div>1</div> <div>2</div> <img src="http://unclosed.example.com"> <div>3</div> <!-- will be indented too far --> <div>4</div> </div> </body> </html> """ parser = MyHTMLParser() parser.feed(html_content)
解决方案(仅使用Python内置库)
可以通过维护标准自闭合标签集合,在自定义解析器中调整深度逻辑来解决:
from html.parser import HTMLParser # 定义HTML标准中的自闭合标签集合 SELF_CLOSING_TAGS = {'img', 'br', 'input', 'meta', 'link', 'area', 'base', 'col', 'command', 'embed', 'hr', 'keygen', 'param', 'source', 'track', 'wbr'} class MyHTMLParser(HTMLParser): def __init__(self): super().__init__() self.depth = 0 def handle_starttag(self, tag, attrs): print('|'*self.depth + tag) # 仅非自闭合标签增加深度 if tag not in SELF_CLOSING_TAGS: self.depth += 1 def handle_endtag(self, tag): # 仅非自闭合标签减少深度 if tag not in SELF_CLOSING_TAGS: self.depth -= 1 html_content = """ <html> <head> <title>test</title> </head> <body> <div> <img src="http://closed.example.com" /> <div>1</div> <div>2</div> <img src="http://unclosed.example.com"> <div>3</div> <!-- 现在缩进正常 --> <div>4</div> </div> </body> </html> """ parser = MyHTMLParser() parser.feed(html_content)
逻辑说明
- 预先定义符合HTML标准的自闭合标签集合;
- 在
handle_starttag中,只有当标签不属于自闭合标签时,才增加深度; - 在
handle_endtag中,同样只对非自闭合标签执行深度减少操作; - 无论自闭合标签是否带结尾斜杠,都不会干扰后续元素的深度计算,解决缩进异常问题。
内容的提问来源于stack exchange,提问作者flawr
相关产品推荐
相关产品推荐

