2017-05-09 98 views
2

我尝试将HTML页面转换为树结构。我已经得到的这个类(我删除了我实际上做与每个标签,因为它是不相关):如何处理没有结尾斜杠的空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 

我需要知道什么时候每个元素已经被关闭,以正确地创建树。我如何知道标签是否为空元素?

+2

从文档: _“此解析器不检查结束标签是否匹配开始标签或调用通过关闭外部元素隐式关闭的元素的结束标记处理程序。“_ https://docs.python.org/3/library/html.parser.html – Hamish

+0

您应该输入严格的XML,其中' '标签不再有效,您必须将其写为''或跟踪可能以空标签形式出现的标签列表,如'
'或''标签。 –

+1

http://stackoverflow.com/questions/3115448/best-way-to-convert-the-this-html-file-into-an-xml-file-using-python –

回答

2

检查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) 
    

祝你好运:)

+1

您的解决方案奏效,谢谢。解析一个Twitter页面,我发现他们使用'link'标签作为一个空元素,但它不在你链接的列表中。我不知道它是否应该(也许这不是标准),但我把它放在那里以防有人遇到同样的问题。 – Arno

相关问题