Beautiful Soup,当前为4.4.0版本,简称 bs4,bs4不属于python标准库,需安装:pip install bs4
官方中文文档:https://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/
简单来说,BeautifulSoup 就是 Python 的一个 HTML 或 XML 的解析库,我们可以用它来方便地从网页中提取数据。
bs4 最大的特点是简单易用,不像正则和 xPath 需要刻意去记住很多特定语法,尽管那样会效率更高更直接。
bs4 自动将输入文档转换为 Unicode 编码,输出文档转换为 utf-8 编码。
1. Beautiful Soup 支持的解析器
bs 在使用时需要指定一个“解析器”
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
html.parse | BeautifulSoup(markup,“html.parser”) | Python 的内置标准库,执行速度适中 、文档容错能力强 | Python 2.7.3 or3.2.2) 前的版本中文容错能力差 |
lxml | BeautifulSoup(markup,“lxml”) | 速度快、文档容错能力强 | 需额外安装:pip install lxml |
xml | BeautifulSoup(markup,“xml”) | 速度快、唯一支持 XML 的解析器 | 同属 lxml 库,需额外安装:pip install lxml |
html5lib | BeautifulSoup(markup,“html5lib”) | 最好的容错性、以浏览器的方 式解析文档、生成 HTML5 格式的文档 | 速度慢、不依赖外部 扩展 |
通过以上对比可以看出,lxml 解析器有解析 HTML 和 XML 的功能,而且速度快,容错能力强,所以推荐使用lxml解析器。
2. 初始化bs对象——BeautifulSoup(markup,features)
features是解析器。
markup是网页数据,只支持str类型的网页数据,因为他的源码中markup="",所以如果需要他解析一个html文件,则需先打开这个文件:
from bs4 import BeautifulSoup
#简易写法
data = BeautifulSoup(open('练习.html','r+',encoding='utf-8'),'lxml')
print(data)
一般是搭配其他爬虫库使用,将爬取到的页面数据转换成字符串类型,然后交由bs解析。
from bs4 import BeautifulSoup
import urllib3
http = urllib3.PoolManager()
res = http.request('get','http://www.baidu.com/')
html = res.data.decode('utf-8')
soup = BeautifulSoup(html,'lxml')#实例化一个bs对象
print(type(soup))#<class 'bs4.BeautifulSoup'>
print(soup)
3. 获取某个结构化元素及其属性、文本
获取某一类标签的第一个:bs对象.标签名
获取这个节点的所有属性:bs对象.标签名.attrs 返回一个字典,key是属性名,value是属性值,是一个列表,如果该属性有多个值,则每个值单独为一个元素。
获取这个节点的指定属性的值:bs对象.节点[“属性”] 或者 bs对象.标签名.attrs[“属性”] 返回一个列表,如果该属性有多个值,则每个值单独为一个元素。
获取该节点的文本:bs对象.节点.string
html = '''
<div id="cont">
<ul class="slist">
<li class="item-0">web开发</li>
<li class="item-1"><a href="link2.html">爬虫开发</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">数据分析</span></a></li>
<li class="item-1 active"><a href="link4.html">深度学习</a></li>
<li class="item-0"><a href="link5.html">机器学习</a></li>
</ul>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print(soup.li)#获取soup中的第一个li标签
print(soup.li.a)#获取soup中的第一个li标签下的第一个a标签,没有就返回None
print(soup.li['class'])#获取soup中第一个li标签的class属性的值
print(soup.li.string)#获取soup中第一个li标签的文本
print(soup.li.attrs)#获取soup中第一个li标签的所有属性,返回一个字典
soup1 = BeautifulSoup('<li class="item-0 active">'
'<a href="link3.html">'
'<span class="bold">数据分析</span></a></li>','lxml')
print(soup1.li.attrs)#获取soup1中第一个li标签的所有属性,返回一个字典