python - 替换 BeautifulSoup 迭代器中的字符串提前退出?
问题描述
我正在使用 BeautifulSoup 4 尝试迭代字符串列表并替换子字符串,但是我遇到了一个问题,即replace_with
在生成器上执行一段时间迭代会strings
提前退出循环。
例如,给定这段代码
from bs4 import BeautifulSoup
s = BeautifulSoup("<p>a</p><p>b</p><p>c</p>", features="html.parser")
for st in s.strings:
st.replace_with('replace')
的最终内容s
将是<p>replace</p><p>b</p><p>c</p>
,而预期的行为将是 a、b 和 c 各自被替换。strings
使用调试器单步执行确认在替换发生后迭代停止,基本上只执行一次迭代并提前退出。
在实践中,我将更新字符串的子部分并用新创建的 BeautifulSoup 对象替换它们,因此更简单的替换方法可能不起作用:
updated = st.replace(keyword, f'<a href="url/{keyword}">{keyword}</a>')
st.replace_with(BeautifulSoup(updated, features="html.parser"))
是否有解决方法或更正确的方法来做到这一点?
解决方案
您将获得此输出 b'coz,如replace_with()的文档中所述
PageElement.replace_with() 从树中删除标签或字符串,并将其替换为您选择的标签或字符串
一旦从树中移除,它就不再有next_element并且生成器会提前退出。我们可以使用此代码检查这一点
from bs4 import BeautifulSoup
s = BeautifulSoup("<p>a</p><p>b</p><p>c</p>", features="html.parser")
for st in s.strings:
print(st.next_element)
st.replace_with('replace')
print(st)
print(st.next_element)
输出
<p>b</p>
a
None
之后是. replace_with()
_next_element
None
一种方法是@cody 提到的方法,即。使用 list() 一次获取所有值。
另一种方法是存储next_element
并在之后设置它replace_with()
以让生成器产生更多元素。
from bs4 import BeautifulSoup
s = BeautifulSoup("<p>a</p><p>b</p><p>c</p>", features="html.parser")
for st in s.strings:
next=st.next_element
st.replace_with('replace')
st.next_element=next
print(s)
输出
<p>replace</p><p>replace</p><p>replace</p>
推荐阅读
- spring - 在登录Spring Boot之前解码密码
- javascript - Quasar + Vue + SSR - 如何隐藏敏感数据,如 API 密钥
- regex - Oracle 11g 中 CLOB 上的 REGEXP_REPLACE 失败并出现 - 没有更多数据可以从套接字读取
- sharepoint - 如何在 Sharepoint 中获取术语集的所有子术语?
- python - 如何在 sympy (jupyter notebook) 中将乳胶字符串显示为乳胶输出?
- r - ggplot:3D矩阵:在一个图中绘制多条线并在同一页面上绘制多个图
- wso2 - 有没有办法不在 wso2 APIM 中指定版本
- ios - 面临 Xcode 无法成功运行代码部分并在 AWS 站点上激活以禁用的问题
- mongodb - 如何在猫鼬中使用聚合和查找进行过滤?
- python - 从 AWS S3 读取数据