首页 > 解决方案 > BeautifulSoup decode_contents() 返回 < 而不是 <

问题描述

我正在尝试做的事情:我想将带有 class="list_detail" 的 li 标签与之前的 li 合并

在下面的代码中,第一个 list_detail 按预期工作,给出 <li>cccc<br/>dddd</li>

第二个给出
<li>aaa<br/>&lt;p&gt;bb&lt;i&gt;b&lt;/i&gt;b&lt;/p&gt;</li>

它应该给 <li>aaa<br/><p>bb<i>b</i>b</p></li>

from bs4 import BeautifulSoup, Tag, NavigableString
soup = BeautifulSoup("""
<ol>
    <li>cccc</li><li class='list_detail'>dddd</li>
    <li>aaa</li><li class='list_detail'><p>bb<i>b</i>b</p></li>
</ol>""", "html.parser")
details = soup.findAll("li", attrs={'class': "list_detail"})

for detail in details:
    new_div = soup.new_tag("br")
    prev = detail.previous_sibling
    prev.append(new_div)
    prev.append(detail.decode_contents())
    detail2 = prev.next_sibling
    print(f"detail2={detail2}")
    print(f"prev.contents={prev.contents}")
    print("prev=" + str(prev))
    if detail2 is not None:
        detail2.decompose()

print (f"soup={soup}")

<li>cccc</li>一个额外的怪癖:当我在and之间添加回车时 <li class='list_detail'>dddd</li>,出现错误 AttributeError: 'NavigableString' object has no attribute 'contents'

标签: pythonbeautifulsoup

解决方案


线

prev.append(detail.decode_contents())

在您的代码中本质上是创建一个 HTML 格式的字符串而不是字符串<p>bb<i>b</i>b</p>,并将其附加到prev标签中,而不是创建标签本身。要作为标记附加<p>bb<i>b</i>b</p>到,您可以通过将上面的行更改为将字符串转换为对象prevbs4.BeautifulSoup

prev.append(BeautifulSoup(detail.decode_contents(), "html.parser"))

推荐阅读