BeautifulSoup:无论有多少封闭标签,都可以进入标签内部

时间:2010-06-02 10:58:50

标签: python beautifulsoup

我正在尝试使用BeautifulSoup从网页中的<p>元素中删除所有内部html。有内部标签,但我不在乎,我只想获得内部文本。

例如,对于:

<p>Red</p>
<p><i>Blue</i></p>
<p>Yellow</p>
<p>Light <b>green</b></p>

我如何提取:

Red
Blue
Yellow
Light green

.string.contents[0]都不能满足我的需要。 .extract()也没有,因为我不想提前指定内部标签 - 我想处理任何可能发生的事情。

BeautifulSoup中是否有“只获取可见HTML”类型的方法?

---- UPDATE ------

根据建议,尝试:

soup = BeautifulSoup(open("test.html"))
p_tags = soup.findAll('p',text=True)
for i, p_tag in enumerate(p_tags): 
    print str(i) + p_tag

但这没有用 - 它打印出来:

0Red
1

2Blue
3

4Yellow
5

6Light 
7green
8

5 个答案:

答案 0 :(得分:67)

简短回答:soup.findAll(text=True)

这已经得到回复,here on StackOverflowBeautifulSoup documentation

<强>更新

澄清一段代码:

>>> txt = """\
<p>Red</p>
<p><i>Blue</i></p>
<p>Yellow</p>
<p>Light <b>green</b></p>
"""
>>> import BeautifulSoup
>>> BeautifulSoup.__version__
'3.0.7a'
>>> soup = BeautifulSoup.BeautifulSoup(txt)
>>> for node in soup.findAll('p'):
    print ''.join(node.findAll(text=True))

Red
Blue
Yellow
Light green

答案 1 :(得分:11)

接受的答案很好,但现在已经6岁了,所以这里的答案是Beautiful Soup 4 version

>>> txt = """\
<p>Red</p>
<p><i>Blue</i></p>
<p>Yellow</p>
<p>Light <b>green</b></p>
"""
>>> from bs4 import BeautifulSoup, __version__
>>> __version__
'4.5.1'
>>> soup = BeautifulSoup(txt, "html.parser")
>>> print("".join(soup.strings))

Red
Blue
Yellow
Light green

答案 2 :(得分:4)

我偶然发现了这个同样的问题,并想分享该解决方案的2019版本。也许它可以帮助别人。

# importing the modules
from bs4 import BeautifulSoup
from urllib.request import urlopen

# setting up your BeautifulSoup Object
webpage = urlopen("https://insertyourwebpage.com")
soup = BeautifulSoup( webpage.read(), features="lxml")
p_tags = soup.find_all('p')


for each in p_tags: 
    print (str(each.get_text()))

请注意,我们首先要一次打印数组内容,然后调用get_text()方法,该方法从文本中剥离标签,因此我们仅打印出文本。

也:

  • 与旧的findAll()相比,在bs4中使用更新的'find_all()'更好
  • 将urllib2替换为urllib.request和urllib.error,请参见here

现在您的输出应该是:

  • 红色
  • 蓝色
  • 黄色

希望这可以帮助寻找更新解决方案的人。

答案 3 :(得分:3)

通常从网站抓取的数据将包含标签。要避免该标签并仅显示文本内容,可以使用text属性。

例如,

const genders = ["male", "female", "other"];

if (genders.indexOf(response.content) > -1) {
    // code if person chose one of the three options.
} else {
    // code here if person did not choose one of the three options and put something else.
}

在此示例中,我从python站点收集了所有段落,并显示了带标签和不带标签的

答案 4 :(得分:0)

首先,使用str将html转换为字符串。然后,在程序中使用以下代码:

import re
x = str(soup.find_all('p'))
content = str(re.sub("<.*?>", "", x))

这称为regex。这个将删除两个html标签之间的任何内容(包括标签)。