文章目录
一、BeautifulSoup简介及安装
1. 简介
简单来说,BeautifulSoup是python的一个解析库,其主要的功能就是解析网页的HTML数据
官方解释如下:
Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。
Beautiful Soup已成为和lxml、html6lib一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度。
2. 安装
直接使用pip安装即可
pip install beautifulsoup4
二、BeautifulSoup使用方法介绍
1. 注意事项
BeautifulSoup在使用时需要指定一个解析器
:
-
html.parse- python 自带,但容错性不够高,对于一些写得不太规范的网页会丢失部分内容
-
lxml- 解析速度快,需额外安装
-
xml- 同属 lxml 库,支持 XML 文档
-
html5lib- 最好的容错性,但速度稍慢
这里的 lxml 和 html5lib 都需要额外安装,自行使用pip安装即可(推荐使用lxml
)
2. 使用方法
例如有如下的HTML文档片段:
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="beautiful 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">...</p>
"""
初始化对象,指定解析器为lxml
:
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'lxml')
2.1 获取标签信息
补全HTML代码、获取标签信息
print(soup.prettify()) # 补全HTML代码
print(soup.p) # 获取整条p标签
print(soup.p.name) # 获取p标签名称
# 获取标签属性
print(soup.p.attrs) # 获取p标签内的所有属性,返回一个字典
print(soup.p['class']) # 获取p标签内的class属性值,返回一个列表
# 获取标签文本
print(soup.p.string) # 获取p标签的文本信息,如果p标签内包含了多个子节点并有多个文本时返回None
print(soup.p.strings) # 获取p标签内的所有文本信息,返回一个生成器
print(soup.p.text) # 获取p标签内的所有文本信息,返回一个列表
print(soup.stripped_strings) # 去掉空白,保留所有的文本,返回一个生成器
2.2 获取元素节点
获取指定元素的父/祖先节点
、子/子孙节点
和兄弟节点
# 获取父·祖先节点
print(soup.p.parent) # 获取p标签的直接父节点
print(soup.p.parents) # 获取p标签的祖先节点,返回一个生成器
# 获取子·子孙节点
print(soup.p.contents) # 获取p标签内的直接子节点,返回一个列表
print(soup.p.children) # 获取p标签内的直接子节点,返回一个生成器
print(soup.p.descendants) # 获取p标签内的子孙节点,返回一个生成器
# 获取兄弟节点
print(soup.a.previous_sibling) # 获取a标签的上一个兄弟节点
print(soup.a.previous_siblings) # 获取a标签前面的所有兄弟节点,返回一个生成器
print(soup.a.next_sibling) # 获取a标签的下一个兄弟节点
print(soup.a.next_siblings) # 获取a标签后面的所有兄弟节点,返回一个生成器
2.3 使用方法选择器
并不是所有的信息都可以简单地通过结构化获取,通常使用 find() 和 find_all() 方法进行查找:
- find()- 返回匹配到的第一个结果
- find_all()- 返回一个包含所有匹配结果的列表
因为 find() 和 find_all() 在使用上几乎一致,所以这里只列出 find_all() 的使用方法
print(soup.find_all(text=re.compile('Lacie'), limit=2)) # 使用正则获取所有文本包含'Lacie'的节点(limit: 限制匹配个数)
print(soup.find_all('a', text='Lacie')) # 获取所有a标签内文本等于'Lacie'的节点(文本完整匹配)
print(soup.find_all('a', id='link2')) # 获取所有a标签内id等于'link2'的节点
print(soup.find_all('a', class_='sister')) # 获取所有a标签内class等于'sister'的节点
print(soup.find_all('a', class_='sister', id='link2')) # 多个搜索条件叠加
print(soup.find_all(name='a')) # 获取所有a节点
print(soup.find_all(attrs={'class': 'sister'})) # 获取所有class属性值为'sister'的节点
2.4 使用CSS选择器
如果你对CSS选择器很熟悉,BeautifulSoup也提供了相应的方法:
.
- 代表class#
- 代表id
print(soup.select('p')) # 获取所有p标签,返回一个列表
print(soup.select('p a')) # 获取所有p标签内的a节点,返回一个列表
print(soup.select('p.story')) # 获取p标签内class为'story'的所有元素,返回一个列表
print(soup.select('.story')) # 获取class为'story'的所有元素,返回一个列表
print(soup.select('.beautiful.title')) # 获取class为'beautiful title'的所有元素,返回一个列表
print(soup.select('#link1')) # 获取id为'link1'的所有元素,返回一个列表