在replaceWith()不起作用后使用find()(使用BeautifulSoup)

时间:2013-03-16 21:55:30

标签: python find beautifulsoup

请考虑以下python会话:

>>> from BeautifulSoup import BeautifulSoup
>>> s = BeautifulSoup("<p>This <i>is</i> a <i>test</i>.</p>"); myi = s.find("i")
>>> myi.replaceWith(BeautifulSoup("was"))
>>> s.find("i")
>>> s = BeautifulSoup("<p>This <i>is</i> a <i>test</i>.</p>"); myi = s.find("i")
>>> myi.replaceWith("was")
>>> s.find("i")
<i>test</i>

请注意第4行后s.find(“i”)缺少的输出!

这是什么原因?有解决方法吗?

编辑:实际上,该示例未演示usecase,即:

myi.replaceWith(BeautifulSoup("wa<b>s</b>"))

每当插入的部分包含非常重要的html代码时,我都看不到如何用其他东西替换这种语法。只是

myi.replaceWith("wa<b>s</b>")

将替换实体的html特殊字符。

3 个答案:

答案 0 :(得分:5)

更简单的答案:致电replaceWith后,请致电s重新生成并清除s = BeautifulSoup(s.renderContents())。然后你可以再次find

答案 1 :(得分:3)

问题似乎是BeautifulSoup对象被视为整个文档。 find遍历文档,询问每个元素后面的下一个元素。但当它到达你的BeautifulSoup("was")时,该对象认为它是整个文档,所以它说它之后什么都没有。这太早就中止了搜索。

我不认为BeautifulSoup被设计为在其他BeautifulSoup对象中包含BeautifulSoup对象。解决方法是不要那样做。为什么你觉得你需要使用第一个表单而不是第二个表单已经有效?如果您想用一些HTML替换元素,请使用Tag替换,而不是BeautifulSoup对象。

答案 2 :(得分:2)

我想,我找到了一个解决方法,它解决了我的问题。我再次重复整个代码作为Python脚本给出一个完整的例子:

from BeautifulSoup import BeautifulSoup
s = BeautifulSoup("<p>This <i>is</i> a <i>test</i>.</p>")
myi = s.find("i")
s2 = BeautifulSoup("wa<b>s</b>")
myi_id = myi.parent.contents.index(myi)
for c in reversed(s2.contents):
    myi.parent.insert(myi_id + 1, c)
myi.extract()

请注意,如果没有reversed(),这将无效。如果跳过它,则不仅要更改元素的顺序。如果您真的想要更改订单,则必须编写以下内容:

for c in list(s2.contents):
    myi.parent.insert(myi_id + 1, c)

有人可以解释,为什么跳过list()会省略<b>s</b>? (请在评论中回答,因为这不是主要问题。)