上一小节我们讲解了如何获取源码并提取文章的标题,我们使用的是soup.title.string ,经过对网页源码的分析,我发现文章的内容大部分都在

...

标签里,就像这样,所以我现在想将所有


的内容获取出来看看是什么结果

如果你用的是新版的Debain或ubuntu,那么可以通过系统的软件包管理来安装:

$ apt-get install Python-bs4

Beautiful Soup 4 通过PyPi发布,所以如果你无法使用系统包管理安装,那么也可以通过 easy_install 或 pip 来安装.包的名字是 beautifulsoup4 ,这个包兼容Python2和Python3.

$ easy_install beautifulsoup4

$ pip install beautifulsoup4

(在PyPi中还有一个名字是 BeautifulSoup 的包,但那可能不是你想要的,那是 Beautiful Soup3 的发布版本,因为很多项目还在使用BS3, 所以 BeautifulSoup 包依然有效.但是如果你在编写新项目,那么你应该安装的 beautifulsoup4 )

如果你没有安装 easy_install 或 pip ,那你也可以 下载BS4的源码 ,然后通过setup.py来安装.

$ Python setup.py install

如果上述安装方法都行不通,Beautiful Soup的发布协议允许你将BS4的代码打包在你的项目中,这样无须安装即可使用.

作者在Python2.7和Python3.2的版本下开发Beautiful Soup, 理论上Beautiful Soup应该在所有当前的Python版本中正常工作

依照前面的方法,我想这里应该这样写

print soup.p.string

但是结果是这样的:

python 获取li标签 python获取标签文本_easy_install

这个结果很令我吃惊,于是我又将代码修改成只输出

标签的结果,然后变成了这样的:

print soup.p

python 获取li标签 python获取标签文本_python 获取li标签_02

不管怎么看,这结果都像是只返回了一个

标签的内容,这令我大惑不解,究竟是为什么?

我们一个问题一个问题的来解决,首先是 soup.p 为什么只返回一个标签

通过点取属性的方式只能获得当前名字的第一个tag:

soup.a

# Elsie

如果想要得到所有的标签,或是通过名字得到比一个tag更多的内容的时候,就需要用到 Searching the tree 中描述的方法,比如: find_all()

soup.find_all('a')

既然这样,那我们的代码应该修改一下:

print soup.find_all('p')

结果是这样的:

python 获取li标签 python获取标签文本_子节点_03

这里的符号显示返回的应该是一个列表,但这具体是怎么回事现在先不管,我们再来看看第二个问题:为什么使用soup.p.string 的时候结果是None?

如果tag只有一个 NavigableString 类型子节点,那么这个tag可以使用 .string 得到子节点:

title_tag.string
# u'The Dormouse's story'
如果一个tag仅有一个子节点,那么这个tag也可以使用 .string 方法,输出结果与当前唯一子节点的 .string 结果相同:
head_tag.contents
# [
The Dormouse's story] 
 
head_tag.string
# u'The Dormouse's story'
如果tag包含了多个子节点,tag就无法确定 .string 方法应该调用哪个子节点的内容, .string 的输出结果是 None :
print(soup.html.string)
# None

这里的描述已经很详细了,我再讲的话有点多余了,所以,一句话总结:

soup.p 这样的方式只能获取第一个p标签,soup.p.string 无法获取获取多个标签里面的文本内容。

很明显这完全不能实现我们需要的功能,我们需要获取多个标签里面的文字,所以我们需要寻找新的方法,好在前面已经给了提示,find_all() , 那好,我们就来看看它到底是什么吧