BS4:如何编辑包含 <> 的 <pre> 的内容

BS4: How to edit the content of a <pre> that contains <>

我有一些 HTML 包含 pre 标签:

<p>Hi!</p><pre><p>Hi!</p></pre>

我想改成:

<p>Hi!</p><pre><p>Bye!</p></pre>

天真的做法似乎是:

from bs4 import BeautifulSoup

markup = """<p>Hi!</p><pre><p>Hi!</p></pre>"""
soup = BeautifulSoup(markup, "html.parser")
pre_tag = soup.pre
pre_tag.string = "<p>bye!</p>"
print(str(soup))

但这给出了 <p>Hi!</p><pre>&lt;p&gt;bye!&lt;/p&gt;</pre>

在给出使用cdata的例子的BS4 docs there's a section on output formatters中:

from bs4.element import CData
soup = BeautifulSoup("<a></a>", 'html.parser')
soup.a.string = CData("one < three")
print(soup.a.prettify(formatter="html"))
# <a>
#  <![CDATA[one < three]]>
# </a>

这看起来像所需要的,除了它还将未格式化的字符包装在 cdata 标记中; pre.

里面不好

这个问题: 看起来方向很模糊,但与 pre 标签的内部无关。

这道题:customize BeautifulSoup's prettify by tag好像有点大材小用了,而且也是BS3时代的

p.s。上面的例子表明想要对pre的内容做各种事情,而不仅仅是把hi改成bye。 (在有人问之前)

或者你可以使用API构造新的内容:

from bs4 import BeautifulSoup

markup = """<p>Hi!</p><pre><p>Hi!</p></pre>"""
soup = BeautifulSoup(markup, "html.parser")
pre_tag = soup.pre

new_tag = soup.new_tag("p")
new_tag.append("bye!")

pre_tag.clear()
pre_tag.append(new_tag)

print(str(soup))

或者您可以将 HTML 提供给另一个 BeautifulSoup 实例并使用它:

from bs4 import BeautifulSoup

markup = """<p>Hi!</p><pre><p>Hi!</p></pre>"""
soup = BeautifulSoup(markup, "html.parser")
pre_tag = soup.pre

soup2 = BeautifulSoup("<p>bye!</p>", "html.parser")

pre_tag.clear()
pre_tag.append(soup2)

print(str(soup))