BeautifulSoup 自动关闭未关闭的 html 标签

BeautifulSoup closes automatically html tags that are unclosed

提问人:Minions 提问时间:8/1/2023 更新时间:8/1/2023 访问量:32

问:

我对 BeautifukSoup 有疑问。每当我解析 HTML 输入时,它都会关闭未关闭的 HTML 标签(例如 或未被错误关闭的标记)。<input>

例如:

from bs4 import BeautifulSoup

tags = BeautifulSoup('<span id="100" class="test">', "html.parser")
print(str(tags))

指纹:

<span id="100" class="test"></span>

我在这里的主要目标是在解析 HTML 输入后保留它的原始形状。

我发现使用“XML”解析器而不是“html.parser”是可能的,但我正在寻找“html.parser”的解决方法。

python html 解析 beautifulsoup

评论

0赞 Barmar 8/1/2023
它将 HTML 解析为 DOM 结构,它不保留实际的 HTML 文本。当您打印它时,它会以标准方式打印它。
0赞 Barmar 8/1/2023
就像将无效的 HTML 加载到浏览器中,然后查看 DevTools 的“元素”选项卡一样。它以规范格式显示它,而不是原始 HTML。
0赞 Barmar 8/1/2023
这与您之前关于属性顺序的问题本质上是相同的问题。
0赞 Minions 8/1/2023
明白了!我想到了这一点,但我无法解决它。可以这样做吗?
0赞 Barmar 8/1/2023
如果要将 HTML 作为文本进行处理,请不要先解析它。编写自己的代码来处理原始文本。

答:

2赞 Andrej Kesely 8/1/2023 #1

您可以戳穿 bs4 内部并修改处理 HTML 的方式(这适用于我的版本):html.parserbs4==4.12.2

from bs4 import BeautifulSoup
from bs4.builder import builder_registry
from bs4.formatter import HTMLFormatter


class UnsortedAttributes(HTMLFormatter):
    def __init__(self):
        super().__init__(
            void_element_close_prefix=""
        )  # <-- use void_element_close_prefix="" here

    def attributes(self, tag):
        yield from tag.attrs.items()


html_text = """\
<closed_tag>
    <my_tag id="xxx">
    <my_other_tag id="zzz">
</closed_tag>"""

builder_registry.lookup("html.parser").empty_element_tags = {"my_tag", "my_other_tag"}

soup = BeautifulSoup(html_text, "html.parser")
print(soup.encode(formatter=UnsortedAttributes()).decode())

指纹:

<closed_tag>
<my_tag id="xxx">
<my_other_tag id="zzz">
</closed_tag>

评论

0赞 Minions 8/1/2023
当我在较长的 html 上测试它时,它似乎跳过了封闭标签。因此,如果我有它将输出,因为我添加了 [tr, td, p] 标签。这是它的本意吗?<tr><td><p> DE </p></td></tr><tr><td><p> DE builder_registry.lookup("html.parser").empty_element_tags
0赞 Andrej Kesely 8/1/2023
@Minions 你不应该添加 // to ,因为它们总是有一些内容。 应仅用于没有内容的标签。<tr><td><p>empty_element_tagsempty_element_tags
0赞 Minions 8/1/2023
啊啊,我明白了。因此,这不会解决 span 包含内容但未关闭的情况,对吧?
1赞 Andrej Kesely 8/1/2023
是的。这似乎是格式错误的 HTML。您可以尝试使用解析器,但此解析器将像浏览器一样处理文档(它将按照 HTML5 规范关闭标记)。html5lib
0赞 Minions 8/1/2023
明白了。好的,再次感谢安德烈!