在解析HTML LXML身体片段(parse html body fragment in lxml)

2019-09-02 15:35发布

我试图解析HTML的一个片段:

<body><h1>title</h1><img src=""></body>

我用lxml.html.fromstring 。 它是推动我疯了,因为它使剥离<body>我的片段标签:

 > lxml.html.fromstring('<html><h1>a</h1></html>').tag
 'html'
 > lxml.html.fromstring('<div><h1>a</h1></div>').tag
 'div'
 > lxml.html.fromstring('<body><h1>a</h1></body>').tag
 'h1'

我也试过document_fromstringfragment_fromstringclean_htmlpage_structure=False ,等...没有什么工作。

我需要使用lxml的,因为我经过HTML片段PyQuery。

我只是想限于lxml不与我的HTML片段混乱。 是否有可能做到这一点?

Answer 1:

.fragment_fromstring()除去<html>标记为好; 基本上,只要你没有一个HTML文件(具有<html>顶级元素和/或一个DOCTYPE), .fromstring()回退到.fragment_fromstring()和该方法将同时删除<html><body>标签,始终。

的解决办法是告诉.fragment_fromstring()给你一个<body> 标签:

>>> lxml.html.fragment_fromstring('<body><h1>a</h1></body>', create_parent='body')
<Element body at 0x10d06fbf0>

这不保留原有的任何属性<body>标签。

另一个解决办法是使用.document_fromstring()方法,将包裹在文档中<html>标签,你可以再次删除:

>>> lxml.html.document_fromstring('<body><h1>a</h1></body>')[0]
<Element body at 0x10d06fcb0>

确实对保存属性<body>

>>> lxml.html.document_fromstring('<body class="foo"><h1>a</h1></body>')[0].attrib
{'class': 'foo'}

使用.document_fromstring()函数在你的第一个例子给出了:

>>> body = lxml.html.document_fromstring('<body><h1>title</h1><img src=""></body>')[0]
>>> lxml.html.tostring(body)
'<body><h1>title</h1><img src=""></body>'

如果你只是想这样做,如果没有 HTML标记,做什么lxml.html.fromstring()不和测试一个完整的文档:

htmltest = lxml.html._looks_like_full_html_bytes if isinstance(inputtext, str) else lxml.html._looks_like_full_html_unicode
if htmltest(inputtext):
    tree = lxml.html.fromstring(inputtext)
else:
    tree = lxml.html.document_fromstring(inputtext)[0]


文章来源: parse html body fragment in lxml