【问题标题】:How to handle an empty HTML element without the ending slash?如何处理没有结尾斜杠的空 HTML 元素?
【发布时间】:2017-10-07 14:36:10
【问题描述】:

我尝试将 HTML 页面转换为树结构。我已经派生了这个类(我删除了我对每个标签所做的实际操作,因为它不相关):

class PageParser(html.parser.HTMLParser):
    def handle_starttag(self, tag, attrs):
        print("start "+tag)
    def handle_endtag(self, tag):
        print("end "+tag)
    def handle_startendtag(self, tag, attrs):
        print("startend "+tag)

我预计空元素会触发handle_startendtag 方法。问题是,当遇到像<meta> 这样的空元素时,只会调用handle_starttag 方法。从我的班级的角度来看,标签永远不会关闭:

parser = PageParser()
parser.feed('<div> <meta charset="utf-8"> </div>')

打印:

start div
start meta
end div

我需要知道每个元素何时关闭才能正确创建树。如何知道标签是否为空元素?

【问题讨论】:

  • 来自文档:“此解析器不会检查结束标记是否与开始标记匹配,也不会为通过关闭外部元素隐式关闭的元素调用结束标记处理程序。” docs.python.org/3/library/html.parser.html
  • 您应该输入严格的 XML,其中 &lt;meta&gt; 标签不再有效,您必须将其写为 &lt;meta/&gt;,或者跟踪可能作为空标签出现的标签列表,比如&lt;br/&gt;&lt;meta/&gt; 标签。

标签: python html python-3.x parsing html-parsing


【解决方案1】:

检查documentation,特别是这个例子:

解析具有一些属性和标题的元素:

>>>parser.feed('<img src="python-logo.png" alt="The Python logo">')
Start tag: img
    attr: ('src', 'python-logo.png')
    attr: ('alt', 'The Python logo')

我们可以确定这是预期的行为。

最好的建议来自@HenryHeath 的评论:使用BeautifulSoup

如果您不想使用它,您可以解决HTMLParser 的预期行为,如下所示:

  • 这是每个HTML 5.2 void element 的列表。
  • 使用这些元素名称创建一个列表:

    void_elements = ['area', 'base', ... , 'wbr']
    
  • handle_starttag 中检查标签是否在void_elements 列表中:

    class PageParser(html.parser.HTMLParser):
        def handle_starttag(self, tag, attrs):
            if tag in void_elements:
                # DO what should happen inside handle_startendtag()
                print("void element "+tag)
            else:
                print("start "+tag)
    

祝你好运:)

【讨论】:

  • 您的解决方案有效,谢谢。解析 Twitter 页面,我发现他们使用 link 标记作为空元素,但它不在您链接的列表中。我不知道它是否应该(也许它不是标准的),但我把它放在那里以防有人遇到同样的问题。
猜你喜欢
  • 2012-10-27
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-16
  • 2011-07-09
  • 1970-01-01
相关资源
最近更新 更多