本文介绍了为什么lxml在解析时关闭这个&q;ol&q;标记?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
以下是一些HTML:
<ol><ul><li>item</li></ul></ol>
和一些使用lxml
的python 3代码解析并重新打印:
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>
在输出中,lxml
在ul
开始之前关闭ol
,这会更改列表结构。
它为什么要这样做?
能否让lxml
以保留列表结构的方式分析HTML?
edit:请注意,如果我将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')
推荐答案
我认为HTML4和HTML5都不允许ul
元素作为ol
元素的子元素。只有li
个元素可以是直接子级。
这可能就是HTML解析器构建不表示输入标记中的嵌套的树结构的原因。传统的HTML 4解析器(可能是在lxml的/libxml的HTML解析器算法中实现的)是否对结构进行了相同的更改,我不记得了,我也不确定在哪里测试它。
当两个HTML5验证器将您的ul
标记为不允许的ol
子级时,当前浏览器似乎保留了该嵌套。
这篇关于为什么lxml在解析时关闭这个&q;ol&q;标记?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!