【问题标题】:find() after replaceWith() doesn't work (using BeautifulSoup)replaceWith() 后的 find() 不起作用(使用 BeautifulSoup)
【发布时间】:2013-03-16 21:55:30
【问题描述】:

请考虑以下 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") 的缺失输出!

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

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

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

每当插入的部分包含自己重要的 html 代码时,我看不出如何用其他内容替换此语法。只是有

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

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

【问题讨论】:

  • 为什么要替换成sometag.renderContents()而不是直接替换成someTag
  • 好的,让我们通过添加一个不同的示例来更具体...(见上文,我再次编辑)

标签: python find beautifulsoup


【解决方案1】:

更简单的答案:调用replaceWith 后,调用s = BeautifulSoup(s.renderContents()) 重新生成和清理s。然后你可以再次find

【讨论】:

  • 请注意,renderContents 现在称为 encode_contents
【解决方案2】:

问题似乎是BeautifulSoup 对象被视为整个文档。 find 遍历文档,向每个元素询问其后的下一个元素。但是当它到达您的BeautifulSoup("was") 时,该对象认为它是整个文档,所以它说它之后没有任何内容。这会过早中止搜索。

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

【讨论】:

  • 我承认我的例子没有说清楚,为什么我需要这个奇怪的结构,我在上面添加了进一步的解释。
  • 不过,您的解释完全正确,谢谢!不过,有一个解决方法会很棒。 (所以不要生我的气,因为我没有将您的答案标记为解决方案。)
  • @thomas:有一个关于类似问题here 的错误报告。一条评论说它已解决,但对我来说似乎仍然很糟糕,我无法理解那里的解释。您可能想对该错误发表评论并展示您的示例,看看他们怎么说。
【解决方案3】:

我想,我找到了一种解决方法,它为我解决了这个问题。我将整个代码作为 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()会省略&lt;b&gt;s&lt;/b&gt;? (请在评论中回答,因为这不是这里的主要问题。)

【讨论】:

  • 之所以需要list,是因为它所说的here:一个元素只能出现在文档中的一个位置。当您执行insert 时,它会从s2.contents 中删除第一个元素,以便将其插入到其他位置。因此,您在迭代 s2 时正在修改它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-07
  • 1970-01-01
  • 2010-11-03
  • 2016-09-30
  • 2016-03-30
  • 1970-01-01
  • 2015-04-06
相关资源
最近更新 更多