用< br>替换线路断裂;在标签中使用美丽的小组

发布于 2025-02-13 16:58:46 字数 1378 浏览 2 评论 0原文

我想使用beautifure来解析一些html,然后替换< blockQuote> 带有< br>标签的标签。这是非常困难的,因为< blockQuote>可能包含其他HTML标签。

我目前的尝试:

from bs4 import BeautifulSoup

html = """
<p>Hello
there</p>
<blockquote>Line 1
Line 2
<strong>Line 3</strong>
Line 4</blockquote>
"""

soup = BeautifulSoup(html, "html.parser")

for element in soup.findAll():
    if element.name == "blockquote":
        new_content = BeautifulSoup(
            "<br>".join(element.get_text(strip=True).split("\n")).strip("<br>"),
            "html.parser",
        )
        element.string.replace_with(new_content)

print(str(soup))

输出应该是:

<p>Hello
there</p>
<blockquote>Line 1<br/>Line 2<br/><strong>Line 3</strong><br/>Line 4</blockquote>

但是,此代码改编自此答案仅在内内没有html标签的情况下工作&lt; blockQuote&gt;。但是,如果有(&lt; strong&gt; line 3&lt;/strong&gt;),则element.String is none none ,上述失败。

是否有可以应付HTML标签的替代方法?

I want to parse some HTML using BeautifulSoup and replace any line breaks (\n) that are within <blockquote> tags with <br> tags. It is extra difficult because the <blockquote> may contain other HTML tags.

My current attempt:

from bs4 import BeautifulSoup

html = """
<p>Hello
there</p>
<blockquote>Line 1
Line 2
<strong>Line 3</strong>
Line 4</blockquote>
"""

soup = BeautifulSoup(html, "html.parser")

for element in soup.findAll():
    if element.name == "blockquote":
        new_content = BeautifulSoup(
            "<br>".join(element.get_text(strip=True).split("\n")).strip("<br>"),
            "html.parser",
        )
        element.string.replace_with(new_content)

print(str(soup))

Output should be:

<p>Hello
there</p>
<blockquote>Line 1<br/>Line 2<br/><strong>Line 3</strong><br/>Line 4</blockquote>

However, this code, adapted from this answer only works if there are no HTML tags within the <blockquote>. But if there are (the <strong>Line 3</strong>) then element.string is None, and the above fails.

Is there an alternative that can cope with HTML tags?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

各自安好 2025-02-20 16:58:46

另一种选择是使用descendants寻找navigablestring s,然后仅替换这些,仅留下其他元素:

from bs4 import BeautifulSoup, NavigableString

html = """
<p>Hello
there</p>
<blockquote>Line 1
Line 2
<strong>Line 3</strong>
Line 4</blockquote>
"""

soup = BeautifulSoup(html, "html.parser")

for quote in soup.find_all("blockquote"):
    for element in list(quote.descendants):
        if type(element) is NavigableString:
            markup = element.string.replace("\n", "<br>")
            element.string.replace_with(BeautifulSoup(markup, "html.parser"))

print(str(soup))

输出:

<p>Hello
there</p>
<blockquote>Line 1<br/>Line 2<br/><strong>Line 3</strong><br/>Line 4</blockquote>

此方法的优势是它没有触摸,例如,html注释:

<blockquote>
<!--
a comment
-->
</blockquote>

变成

<blockquote><br/><!--
a comment
--><br/></blockquote>

您可能期望的。

An alternative would be to use descendants to look for NavigableStrings, and replace just those, leaving other elements alone:

from bs4 import BeautifulSoup, NavigableString

html = """
<p>Hello
there</p>
<blockquote>Line 1
Line 2
<strong>Line 3</strong>
Line 4</blockquote>
"""

soup = BeautifulSoup(html, "html.parser")

for quote in soup.find_all("blockquote"):
    for element in list(quote.descendants):
        if type(element) is NavigableString:
            markup = element.string.replace("\n", "<br>")
            element.string.replace_with(BeautifulSoup(markup, "html.parser"))

print(str(soup))

Output:

<p>Hello
there</p>
<blockquote>Line 1<br/>Line 2<br/><strong>Line 3</strong><br/>Line 4</blockquote>

An advantage of this approach is that it doesn't touch, for example, HTML comments:

<blockquote>
<!--
a comment
-->
</blockquote>

is turned into

<blockquote><br/><!--
a comment
--><br/></blockquote>

as you might expect.

梦里兽 2025-02-20 16:58:46

在使用替换()时,选择更具体的元素并将元素本身作为String上的元素本身工作要简单得多。

这样,您就不必担心其他标签,否则这些标签会以对象形式出现,并且在get_text()的结果中不会表示为字符串。

new_content = BeautifulSoup(
    str(element).replace('\n','<br>'),
    "html.parser",
)
element.replace_with(new_content)
示例
from bs4 import BeautifulSoup

html = """
<p>Hello
there</p>
<blockquote>Line 1
Line 2
<strong>Line 3</strong>
Line 4</blockquote>
"""

soup = BeautifulSoup(html, "html.parser")

for element in soup.find_all('blockquote'):
    new_content = BeautifulSoup(
        str(element).replace('\n','<br>'),
        "html.parser",
    )
    element.replace_with(new_content)

print(str(soup))
输出
<p>Hello 
there</p>
<blockquote>Line 1<br/>Line 2<br/><strong>Line 3</strong><br/>Line 4</blockquote>

It is much simpler to select your elements more specific and work on the elements itself as string while using replace().

This way you don't have to worry about other tags that would otherwise be present as objects and are not represented as string in result of get_text().

new_content = BeautifulSoup(
    str(element).replace('\n','<br>'),
    "html.parser",
)
element.replace_with(new_content)
Example
from bs4 import BeautifulSoup

html = """
<p>Hello
there</p>
<blockquote>Line 1
Line 2
<strong>Line 3</strong>
Line 4</blockquote>
"""

soup = BeautifulSoup(html, "html.parser")

for element in soup.find_all('blockquote'):
    new_content = BeautifulSoup(
        str(element).replace('\n','<br>'),
        "html.parser",
    )
    element.replace_with(new_content)

print(str(soup))
Output
<p>Hello 
there</p>
<blockquote>Line 1<br/>Line 2<br/><strong>Line 3</strong><br/>Line 4</blockquote>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文