python - BeautifulSoup decode_contents() 返回 < 而不是 <
问题描述
我正在尝试做的事情:我想将带有 class="list_detail" 的 li 标签与之前的 li 合并
在下面的代码中,第一个 list_detail 按预期工作,给出
<li>cccc<br/>dddd</li>
第二个给出
<li>aaa<br/><p>bb<i>b</i>b</p></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'
解决方案
线
prev.append(detail.decode_contents())
在您的代码中本质上是创建一个 HTML 格式的字符串而不是字符串<p>bb<i>b</i>b</p>
,并将其附加到prev
标签中,而不是创建标签本身。要作为标记附加<p>bb<i>b</i>b</p>
到,您可以通过将上面的行更改为将字符串转换为对象prev
bs4.BeautifulSoup
prev.append(BeautifulSoup(detail.decode_contents(), "html.parser"))
推荐阅读
- scala - 为 Kafka appender 配置 log4j.properties,解析属性 bootstrap.servers 时出错
- javascript - 将过滤器搜索与分页集成
- javascript - 将缓冲区作为 Uint8Array 传递,不带空字节
- asynchronous - 如何在不使用任何外部依赖项的情况下执行 async/await 函数?
- shiny - 调用已编译的 rstan 模型到 Shiny App
- react-native - 如何从两个 package.json 构建 react-native 应用程序?
- laravel-5 - Laravel 5.4 关系 - 使用正确的类型
- java - 焦点/滚动recyclerView到最后一个项目
- reactjs - 我们可以将状态变量作为参数从组件内部定义的 react js 函数传递给外部 util 函数吗?
- angular - Angular 7 如何手动触发 mat-error?