我目前面临一个无法解释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细节,如大多数命名实体,如
或未关闭/自关闭的标记(。
居中内容已经用CSS完成了很长时间了,没有理由再使用<center>
了(事实上,它已被弃用(。但它仍然有效,如果您坚持使用它,请切换嵌套。
<center><p><code>git clone https://github.com/AlexeyAB/darknet.git</code></p></center>