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”的方法呢?
----更新------
根据建议,我尝试了:
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 个回答
12
我遇到了同样的问题,想分享一下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()方法,这个方法会把文本中的标签去掉,这样我们只打印出纯文本。
另外:
- 在bs4中,使用更新版的'find_all()'比旧版的findAll()要好。
- urllib2被urllib.request和urllib.error替代,具体可以查看这里。
现在你的输出应该是:
- 红色
- 蓝色
- 黄色
- 浅色
希望这能帮助到正在寻找更新解决方案的人。
17
这个被认可的回答很好,但已经有6年了,所以这里是当前的Beautiful Soup 4版本的回答:
>>> 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
79
简短的回答是:soup.findAll(text=True)
这个问题已经有人回答过了,可以在StackOverflow上找到答案,还有在BeautifulSoup的文档里。
更新:
为了更清楚,这里有一段可以运行的代码:
>>> 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