【问题标题】:Get real text with beautifulSoup after unwrap()在 unwrap() 之后使用 beautifulSoup 获取真实文本
【发布时间】:2017-06-21 14:59:14
【问题描述】:

我需要你的帮助:我有 <p> 标签和许多其他标签,如下例所示:

<p>I <strong>AM</strong> a <i>text</i>.</p>

我只想得到“我是一个文本”,所以我 unwrap() 标签 strongi 使用下面的代码:

for elem in soup.find_all(['strong', 'i']):
    elem.unwrap()

接下来,如果我打印soup.p 一切正常,但如果我不知道我的字符串所在的标签名称,问题就开始了!

下面的代码应该更清楚:

from bs4 import BeautifulSoup

html = '''
<html>
    <header></header>
    <body>
        <p>I <strong>AM</strong> a <i>text</i>.</p>
    </body>
</html>
'''
soup = BeautifulSoup(html, 'lxml')

for elem in soup.find_all(['strong', 'i']):
    elem.unwrap()

print soup.p 
# output :
# <p>I AM a text.</p>

for s in soup.stripped_strings:
    print s
# output 

'''
I
AM
a
text
.
'''

为什么 BeautifulSoup 将我的所有字符串分开,而我之前将它与我的 unwrap() 连接起来?

【问题讨论】:

  • 你应该取消p...
  • 我准确地说,我需要将父母(在我的情况下,P)保留在我的汤中,因为我需要知道我提取的文本所在的标签。

标签: python beautifulsoup


【解决方案1】:

如果你.unwrap()标签,你删除标签,并将内容放在父标签中。但是文本没有合并,因此,你得到了一个NavigableStrings的列表(str的子类):

>>> [(c,type(c)) for c in soup.p.children]
[('I ', <class 'bs4.element.NavigableString'>), ('AM', <class 'bs4.element.NavigableString'>), (' a ', <class 'bs4.element.NavigableString'>), ('text', <class 'bs4.element.NavigableString'>), ('.', <class 'bs4.element.NavigableString'>)]

因此,这些元素中的每一个都是一个分隔的文本元素。因此,尽管您删除了标签本身并注入了文本,但这些字符串并未连接起来。这似乎是合乎逻辑的,因为左侧和右侧的元素可能仍然是标签:通过解开&lt;strong&gt;,您并没有同时解开&lt;i&gt;

不过,您可以使用.text 来获取全文:

>>> soup.p.get_text()
'I AM a text.'

或者你可以决定join元素一起:

>>> ''.join(soup.p.strings)
'I AM a text.'

【讨论】:

  • 很清楚!谢谢你。我以为它会自动合并它..没有办法在旅途中加入它?在我的示例中,我知道我需要合并 p 的文本,但在现实生活中,我不知道我的父标签是什么 :(
  • The Beautiful Soup 4 文档仅提及.get_text() - 我不建议使用.text(或.string,由于某种原因也存在)。
  • @Quentin:我不知道。从这个意义上说,.get_text() 可能是最好的:它使树保持原样,并且将递归地获取文本。
  • @Quentin 您可以通过在展开元素的开头和结尾以及之前和之后检查 NavigableStrings 并将它们替换为已连接的 @987654337 来“随时随地”加入它@恰如其分。不过,API 中没有内置任何内容。
猜你喜欢
  • 2016-03-28
  • 1970-01-01
  • 2019-03-09
  • 2021-10-10
  • 1970-01-01
  • 1970-01-01
  • 2021-07-20
  • 2019-05-23
  • 1970-01-01
相关资源
最近更新 更多