BeautifulSoup4
与 lxml
一样,是一个 html
解析器,主要功能也是解析和提取数据。
BeautifulSoup4
是 爬虫
必学的技能。BeautifulSoup
最主要的功能是从网页抓取数据,Beautiful Soup
自动将输入文档转换为 Unicode
编码,输出文档转换为 utf-8
编码,不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup
就不能自动识别编码方式了,然后,仅仅需要说明一下原始编码方式就可以了。
BeautifulSoup
支持 Python
标准库中的 HTML
解析器,还 支持一些第三方的解析器
,如果不安装它,则 Python
会使用 Python
默认的解析器。
使用步骤
# 1、安装
$ pip install bs4# 2、导入
from bs4 import BeautifulSoup# 3、创建对象
soup = beautifulsoup(解析内容,解析器)# 服务器响应文件生成对象(注意编码格式)
soup = BeautifulSoup(response.read().decode('utf-8'), 'lxml')
# 本地文件生成对象(注意编码格式)
soup = BeautifulSoup(open('test.html', 'r', encoding='utf-8'), 'lxml')
常用解析器:html.parser
、lxml
、xml
、html5lib
,其中 lxml
解析器更强大,速度更快,推荐使用 lxml
解析器,附 beautifulsoup 菜鸟教程。
# 如果解释器不存在,则需要进行安装,其他解释器也一样
$ pip install lxml
列举一下比较常用的几个方法 find()、find_all()、select()
,推荐使用 select()
支持选择器写法,还有一些属性的基本获取,更多的方法知道使用在查就行了,懒的列。
本地测试数据
Document
- 北京
- 上海
- 深圳
- 武汉
新浪微博哈哈哈
- 大连
- 沈阳
- 长沙
百度一下
本地测试代码
# 导入
from bs4 import BeautifulSoup# 本地文件生成对象
soup = BeautifulSoup(open('test.html', 'r', encoding='utf-8'), 'lxml')# 根据标签名查找节点
# 找到第一个符合条件的节点返回
print(soup.a) # 新浪微博# 获取标签的属性和属性值
print(soup.a.attrs) # {'href': '', 'id': 'xlwb'}# soup.find():返回单个对象# 根据 title 值来找到对应的标签对象
print(soup.find('li', title="dzm")) # - 武汉
# 根据 class 值来找到对应的标签对象
# print(soup.find('li', class="c1")) # 关键字 class 存在 python 中会报错无法使用
print(soup.find('li', class_="c1")) # 可以通过加下划线来使用属于系统关键字的属性 - 北京
# soup.find_all():返回数组# 查找所有 a 标签
print(soup.find_all('a')) # [新浪微博, 百度一下]# 查找所有 a | span 标签
print(soup.find_all(['a', 'span'])) # [新浪微博, 哈哈哈, 百度一下]# limit 限制查找数量,查找前几个数据
print(soup.find_all('li', limit=2)) # [- 北京
, - 上海
]#【推荐使用】soup.select():返回数组,制成选择器写法# 查找所有 a 标签
print(soup.select('a')) # [新浪微博, 百度一下]# 查找所有 a | span 标签
print(soup.select('a,span')) # [新浪微博, 哈哈哈, 百度一下]# 【类选择器】
# 查找 class 属性为 c2 的标签
print(soup.select('.c2')) # [- 上海
]
# 查找 id 属性为 l3 的标签
print(soup.select('#l3')) # [- 深圳
]# 【属性选择器】
# 查找 li 标签中有 id 的标签
print(soup.select('li[id]')) # [- 北京
, - 上海
, - 深圳
, - 武汉
]
print(soup.select('li[id="l2"]')) # [- 上海
]# 【后代选择器】
# 找到 div 下的 li
print(soup.select('div li')) # [- 北京
, - 上海
, - 深圳
, - 武汉
]# 【子代选择器】
# print(soup.select('div>ul>li')) # 这种格式的,空格写不写都行
print(soup.select('div > ul > li')) # [- 北京
, - 上海
, - 深圳
, - 武汉
]# 【推荐使用】节点属性# 获取节点内容(注意:标签对象中只有内容,那么下面两个都行,如果标签对象中还包含其他标签,那么 string 就获取不到了)
# 推荐使用 get_text()
print(soup.select('span')[0].string) # 哈哈哈
print(soup.select('span')[0].get_text()) # 哈哈哈# 获得节点
obj = soup.select('#xlwb')[0] # 新浪微博
# 标签名称
print(obj.name) # a
# 标签属性json
print(obj.attrs) # {'href': '', 'id': 'xlwb'}
# 获取属性值
print(obj.attrs['id']) # xlwb
print(obj.attrs.get('id')) # xlwb
print(obj.get('id')) # xlwb
print(obj['id']) # xlwb