提问人:dfrankow 提问时间:7/27/2021 更新时间:7/29/2021 访问量:119
为什么 lxml 在解析时关闭这个“ol”标签?
Why is lxml closing this "ol" tag when parsing?
问:
以下是一些 HTML:
<ol><ul><li>item</li></ul></ol>
和一些 Python 3 代码来解析它并重新打印它:lxml
import sys
from lxml import etree, html
document_root = html.fromstring(sys.stdin.read())
print(etree.tostring(document_root, encoding='unicode'))
输出如下:
<div><ol/><ul><li>item</li></ul>
</div>
在输出中,关闭 before 开始,这将更改列表结构。lxml
ol
ul
它为什么要这样做?
我可以让 lxml
以保留列表结构的方式解析 HTML 吗?
编辑:请注意,如果我替换为 (),或者如果我替换为 (),则此示例可以很好地解析。输出与输入相同。ul
ol
<ol><ol><li>item</li></ol></ol>
ol
ul
<ul><ul><li>item</li></ul></ul>
我无法控制 HTML,它可能来自任何地方。
我正在使用从 PyPi 安装的 lxml 4.6.3 和 python 3.9。
或者,有没有另一种方法可以解析 HTML,我可以从中提取列表文本,同时保留 Python 中的列表结构?
正如您所知,我正在使用 lxml 来删除属性,所以下面是更接近我的用例的代码。但是,我想先给出最小的可重现测试用例。
更接近我的用例的代码:
import sys
import lxml.html.clean as clean
from lxml import etree, html
document_root = html.fromstring(sys.stdin.read())
cleaner = clean.Cleaner(safe_attrs_only=True, safe_attrs=frozenset())
cleansed = cleaner.clean_html(document_root)
# Do something with the lists in cleansed, defined by ol, ul, and li ..
print(etree.tostring(cleansed, encoding='unicode')
答:
1赞
Martin Honnen
7/29/2021
#1
我认为 HTML 4 和 HTML5 都不允许将元素作为元素的子元素。只有元素可以是直接子元素。ul
ol
li
这可能就是为什么 HTML 解析器构建一个树结构,而不是表示输入标记中的嵌套。一个“传统的”HTML 4 解析器,就像可能在 lxml/libxml 的 HTML 解析器算法中实现的那样,是否对结构做了同样的更改,我不记得了,我不确定在哪里测试它。
虽然两个 HTML5 验证器将您标记为 的不允许的子级,但当前的浏览器似乎保留了这种嵌套。ul
ol
评论
html
document_root = etree.fromstring(sys.stdin.read())
ul
ol
ul
ol
ul
ol