Python3解析库BeautifulSoup
Python3解析库BeautifulSoup
镇长上一篇,学习如何请求网络数据,接下来学习使用Beautiful Soup解析请求到的数据。
Beautiful Soup是一个可以从HTML和XML文件中提取数据的Python库。
版本:4.4.0
安装Beautiful Soup
确保安装Python3之后,只需一行命令。
1 | pip install beautifulsoup4 |
注意,Mac中可能需要使用
pip3 install beautifulsoup4
安装完BeautifulSoup后,我们还需要HTTP解析器,例如三方解析器lxml
1 | pip install lxml |
万事俱备只欠东风!
快速开始
1 | >>>from bs4 import BeautifulSoup |
对象种类
BeautifulSoup将复杂的HTML文档转为一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为四种:Tag, NavigableString, BeautifulSoup, Comment。
Tag
Tag对象与XML和HTML原生文档中的tag相同。例如:
1 | >>>tagb = soup.b |
下面介绍两个最重要的属性:name 和 attributes 。Tag有很多属性和方法,在遍历文档树和搜索文档树中详细介绍。
Name
使用.name
获取和修改tag的名字
1 | >>> tag.name |
Attributes
一个tag有很多属性。例如:前面的tag<b class="boldest">
,有一个class
属性。
1 | >>> tag['class'] |
获取所有的属性
1 | tag.attrs |
另外tag的属性可以添加,删除和修改。操作方法和字典一样
注意:多值属性,一个属性可以同时存在多个值
NavigableString
字符串常被包含在tag中,使用NavigableString类来包装tag中的字符串:
1 | >>> tag.string |
BeautifulSoup
BeautifulSoup对象并不是真正的HTML或XML的tag,所以它没有name和Attribute属性。有时我们需要.name
查看,所以它包含一个值为[documnet]
的特殊属性.name
1 | >>>soup.name |
Comment
上面三个覆盖了HTML和XML中的所有内容。但是还有一些特殊对象。
1 | >>> markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>" |
Comment 对象是一个特殊类型的
NavigableString
对象
Comment
对象会使用特殊的格式输出:
1 | >>> print(soup.b.prettify()) |
遍历文档树
🌰:
1 | >>> html_doc = """ |
子节点
一个Tag可能包含多个字符串或其它的Tag,这些都是这个Tag的子节点。Beautiful Soup提供了许多操作和遍历子节点的属性。
Tag的名字
操作文档树最简单的方法就是告诉想获取标签的名称:
1 | >>> soup.head |
.contents 和 .children
.contents
属性可以将tag的子节点以列表的方式输出:
1 | >>> head_tag = soup.head |
注意:字符串没有子节点,所以字符串没有
.contents
属性。
1 | >>> for child in title_tag.children: |
.descendants
.contents
和.children
属性仅包含tag的直接子节点。.descendants
属性可以对所有tag的子孙节点进递归循环
1 | >>> for child in head_tag.descendants: |
.string
1 | >>> title_tag.string |
.strings 和 stripped_strings
- 如果tag中包含多个字符串,可以使用
.strings
来循环获取。
1 | for string in soup.strings: |
- 输出的字符串中可以包含了很多空格或空行,使用
.stripped_strings
可以去除多余空白内容。
1 | for string in soup.stripped_strings: |
父节点
.parent
.parent
属性获取某个元素的父节点。
字符串也有父节点
的父节点是BeautifulSoup对象 BeautifulSoup对象的父节点是None
.parents
.parents
递归获取所有的父辈节点。
兄弟节点
使用.next_sibling
和.previous_sibling
属性来查询兄弟节点
通过.next_siblings
和.previous_siblings
属性可以对当前节点的兄弟节点迭代输出。
搜索文档树
Beautiful Soup定义了很多搜索方法。例如:find() 和 find_all()。
过滤器
常见的过滤器类型,如下几种:
字符串
最简单的过滤器,例如:查找<b>
标签可以写成find_all('b')
。
正则表达式
匹配符合正则表达式的内容。
列表
匹配列表中所有元素内容。
TRUE
可以匹配任何值。
方法
可以定义一个接受一个参数的方法,返回布尔类型。如果是TRUE表示当前元素匹配找到,否则为找到。
find_all
find_all( name , attrs , recursive , string , **kwargs )
搜索所有当前tag的所有tag子节点,并判断是否符合过滤器的条件。
- name
name
参数可以查找所有名字为name的tag。
1 | soup.find_all("title") |
- keyword参数
如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索。
1 | # id |
- 按Class搜索
按照类名搜索,但是由于class
是保留字,所以使用class_
代替。
1 | >>> soup.find_all("a", class_="sister") |
- String参数
使用string参数搜索和使用name参数的可选值一样。
1 | >>> soup.find_all(string="Elsie") |
- limit参数
使用limit限制返回的数量
1 | >>> soup.find_all("a", limit=2) |
- recursive参数
将recursive设置为False,只会搜索tag的直接子节点。
find
find()和find_all()不同的是,前者直接返回结果,后者返回包含值的列表。
CSS选择器
在BeautifulSoup对象的select()
方法传入字符串参数,即可以使用CSS选择器。
小结
本文整理BeautifulSoup的基础知识和使用方法。