lxml etree HTML 解析器更改节点的顺序 (<center> 内部 <p>)



我目前面临一个无法解释etree行为的问题。以下代码演示了我面临的问题。我想解析如下所示的 HTML 字符串,更改元素的属性并在完成后重新打印 HTML。

from lxml import etree
from io import StringIO, BytesIO
string = "<p><center><code>git clone https://github.com/AlexeyAB/darknet.git</code></center></p>"
parser = etree.HTMLParser()
test = etree.fromstring(string, parser)
print(etree.tostring(test, pretty_print=True, method="html")

我得到这个输出:

<html><body>
<p></p>
<center><code>git clone https://github.com/AlexeyAB/darknet.git</code></center>
</body></html>

如您所见(让我们忽略 etree 添加的<html><body>标签(,节点的顺序已更改!用于包装 <center> 标记的 <p> 标记现在丢失其内容,并且该内容将在</p>标记关闭后添加。啊?

当我省略<center>标签时,突然间解析正确完成:

from lxml import etree
from io import StringIO, BytesIO
string = "<p><code>git clone https://github.com/AlexeyAB/darknet.git</code></p>"
parser = etree.HTMLParser()
test = etree.fromstring(string, parser)
print(etree.tostring(test, pretty_print=True, method="html"))

使用正确的输出:

<html><body><p><code>git clone https://github.com/AlexeyAB/darknet.git</code></p></body></html>

我在这里做错了什么吗?我必须使用 HTML 解析器,因为在不使用它时我会遇到很多解析错误。我也无法更改<p><center>标签的顺序,因为我以这种方式阅读它们。

<center>是一个块级元素。

<p>不能合法地包含块级元素。

因此,解析器在遇到<center>时会关闭<p>

使用有效的HTML - 或XML解析器,它不关心HTML规则(但作为交换,不能处理一些HTML细节,如大多数命名实体,如&nbsp;或未关闭/自关闭的标记(。

居中内容已经用CSS完成了很长时间了,没有理由再使用<center>了(事实上,它已被弃用(。但它仍然有效,如果您坚持使用它,请切换嵌套。

<center><p><code>git clone https://github.com/AlexeyAB/darknet.git</code></p></center>

最新更新