一. 引入
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.
二. 安装
pip install beautifulsoup4
三. 快速开始
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">It's a good story</p>
<p>
<!--Hey, buddy. Want to buy a used parser?-->
</p>
"""
-
如何使用?
将一段文档传入BeautifulSoup 的构造方法,就能得到一个文档的对象, 可以传入一段字符串或一个文件句柄.
from bs4 import BeautifulSoup
soup = BeautifulSoup(open("index.html"))
soup = BeautifulSoup("<html>data</htmol>")
- 使用BeautifulSoup解析这段代码,能够得到一个 BeautifulSoup 的对象,使用该对象下的prettify()方法,能按照标准的缩进格式的结构输出:
四. 常用方法
1. 获取标签
-
BeautifulSoup 对象表示的是一个文档的全部内容.大部分时候,可以把它当作 Tag 对象,它支持 遍历文档树 和 搜索文档树 中描述的大部分的方法。因为 BeautifulSoup 对象并不是真正的HTML或XML的tag,所以它没有name和attribute属性.但有时查看它的 .name 属性是很方便的,所以 BeautifulSoup 对象包含了一个值为 “[document]” 的特殊属性 .name
-
可以通过 soup.p 来获得文档中第一个 p 标签,当然了,你想要获得什么标签, 通过**.name**就能获得任意标签。
通过上图可以看出,soup.p的类型是 bs4.element.Tag对象,Tag对象也能通过 .name方法,获得标签,如下:- 通过 .name方法获得到文档中第一个p标签下的b标签
- 通过 .name方法获得到文档中第一个p标签下的b标签
-
获取多个标签,如上,我们发现,只能获得到文档中的一个p标签,可以通过**find_all()**方法获得多个p标签。如下图:
-
find_all返回的是一个列表,列表中每一个元素为 Tag对象
-
如需获得一个标签,也可以使用find方法,使用与find_all类似,只是返回值是一个 Tag对象。这里,提一点,soup.find_all(‘p’)可以简写成soup(‘p’),这两个是等价的。
-
添加过滤条件,获取到想要的标签:
- 假设,我要获取 p 标签中 class属性名称为"story"的p 标签
PS: 这里需要注意一下,class是python中的关键字,当需要使用class属性时,需要使用**class_**加以区分。当然了,你也可以通过该标签的其它属性,如 id=xxx,这样也行。当然,还有其它写法,如下:
- 假设,我要获取 p 标签中 class属性名称为"story"的p 标签
-
过滤条件也可以是正则表达式
- 假设,我要获取文档中 a标签,href属性包含 lacie,如下:
- 假设,我要获取文档中 a标签,href属性包含 lacie,如下:
PS:以上,不论是 find_all还是find都适用,注意一点,过滤条件可以写自行组合,如下:
soup.find('a',class_='story',href=re.compile(r'xxxx'))
- 使用CSS选择器来查找标签
-
通过标签名来查找,如下:
从上图可以看出,跟 find_all() 差不多。 -
通过CSS的类名查找,如下:
-
通过tag的id查找,如下:
-
同时用多种CSS选择器查询元素,如下:(可以使用逗号将两个CSS选择器分隔开来)
PS:soup.select()适合熟悉CSS语法的人使用(当然不是绝对的,不了解CSS也能够使用),这里注意一点,不管是获得的结果是几个,返回的都是一个列表,列表中的每一个元素都是一个 Tag对象,可以再次对 Tag对象使用select find find_all等方法;附一张,如何在浏览器中,获得某个标签的CSS选择器:
2. 获取标签文本内容
- 使用 text方法,(注意返回的标签下所有的文本内容,返回的类型是str)
- 使用 get_text() 方法,与 text方法一样,没有区别。
- .string 方法,
- 很奇怪,竟然返回了None,这是为什么呢?
如果tag只有一个 NavigableString 类型子节点,那么这个tag可以使用 .string 得到子节点。如果tag包含了多个子节点,tag就无法确定 .string 方法应该调用哪个子节点的内容, .string 的输出结果是 None 。什么意思呢?请看下图:
PS:.string方法获得的并不是str类型,而是 <class ‘bs4.element.NavigableString’>,text 和 get_text()方法是获得某个标签下所有的文本内容,而string方法只能获得 tag标签下只有一个 NavigableString 类型子节点的文本内容。
3. 获取标签属性
-
使用 tag[‘xxx’],假设,我需要获取到 a标签中的href属性,如下图:
PS:注意一下,当标签没有该属性时,会报错。 -
使用 tag.get(‘href’,‘http://www.csdn.com’),如果该标签没有href属性,将会把http://www.csdn.com赋值给变量。默认是None,与上一种方法区别在于,属性不存在的话,不会报错。
-
使用 tag.attrs 属性字典进行取值,如下图所示:
五. 关于文档解析器
- Beautiful Soup为不同的解析器提供了相同的接口,但解析器本身时有区别的.同一篇文档被不同的解析器解析后可能会生成不同结构的树型文档。
- 以下列出两种常用文档解析器:
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
Python标准库 | BeautifulSoup(html文档, “html.parser”) | 1.Python的内置标准库 2.执行速度适中3. 文档容错能力强 | Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差 |
lxml HTML 解析器 | BeautifulSoup(html文档, “lxml”) | 1. 速度快 2. 文档容错能力强 | 需要安装 lxml模块,pip install lxml |
End…