展开后获取带有beautifulSoup的真实文本()

时间:2017-06-21 14:59:14

标签: python beautifulsoup

我需要你的帮助:我的<p>标记包含许多其他标记,如下例所示:

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

我想只获得“我是一个文本”所以我打开()标记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()连接起来之前将我的所有字符串分开?

1 个答案:

答案 0 :(得分:2)

如果 .unwrap() 标记,则删除标记,并将内容放在父标记中。但是文本未合并,因此,您获得了NavigableString s 的列表(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'>)]

因此,每个元素都是分隔的文本元素。因此,虽然您删除了标记本身并注入了文本,但这些字符串不会连接在一起。这似乎是合乎逻辑的,因为左侧和右侧的元素仍然是标记:通过展开<strong>您还没有同时解开<i>

但是,您可以使用.text来获取全文:

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

或者您可以决定将join元素组合在一起:

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