一.简介
1.定义
灵活又方便的网页解析库,处理高效,支持多种解析器。利用它不用编写正则表达式即可方便地实现网页信息的提取
2.原理
- 实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中
- 通过调用BeautifulSoup对象中相关的属性或者方法进行标签定位和数据提取
3.特点
- API简单,功能强大:BeautifulSoup提供一些简单的方法和Python式函数,用于浏览,搜索和修改解析树,它是一个工具箱,通过解析文档为用户提供需要抓取的数据
- 支持多种解析器:包括Python标准库中的HTML解析器,还支持一些第三方解析器
- 自动实现编码的转换:BeautifulSoup自动将输入文档转换成Unicode类型,输出文档转换为UTF-8编码。如果文档中没有指定编码,只需我们指定编码即可
二.基本使用
1.步骤
- 第一步:导入BeautifulSoup类
- 第二步:传递初始化参数,并初始化
- 第三步:获取实例对象,操作对象;获取解析,提取数据
2.初始化BeautifulSoup对象
- 如何使用BeautifulSoup解析HTML文档?
- 只需要使用BeautifulSoup类初始化一个对象,然后操作这个对象就可以了
- 需要注意的是:在初始化对象的时候,需要给BeautifulSoup类传递两个参数,HTML代码和HTML解析器
from bs4 import BeautifulSoup
soup = BeautifulSoup(markup,features)
markup:被解析的HTML字符串或文件内容
#使用方式有两种
#1.使用字符串变量
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_str)
#2.使用open()函数打开文件
from bs4 import BeautifuSoup
soup = BeautifulSoup(open(index.html))
features:解析器的类型
#指定解析器:选择指定的解析器来解析文档
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_str,'lxml')
#未指定解析器:选择最默认的解析器来解析文档
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_str)
3.对象的实例化
①将本地的html文档中的数据加载到该对象中
#将本地的html文档中的数据加载到该对象中
fp = open('./test.html','r',encoding='utf-8')
soup = BeautifulSoup(fp,'lxml')
②将互联网上获取的页面源码加载到该对象中
page_text = response.text
soup = BeautifulSoup(page_text,'lxml')
4.提供的用于数据解析的方法和属性
- soup.tagName:返回的是文档中第一次出现的tagName对应的标签
- soup.find():find('tagName'):等同于soup.div;属性定位:soup.find('div',class_/id/attr='song')
- soup.find_all(‘tagName’):返回符合要求的所有标签(列表)
5.select
select(‘某种选择器(id,class,标签...选择器)’),返回的是一个列表
层级选择器:soup.select(‘.tang > ul > li > a’):>表示的是一个层级
oup.select(‘.tang > ul a’):空格表示的是多个层级
6.获取标签之间的文本数据
- soup.a.text/string/get_text()
- text/get_text():可以获取某一个标签中所有的文本内容
- string:只可以获取该标签下面直系的文本内容
7.获取标签中的属性值
- soup.a['href']
8.选择器
作用:用来查找,定位元素,并获取数据
节点选择器是获取数据的基础方法,方法选择器和CSS选择器则是查找,定位元素的常用选择
①节点选择器
选取元素的方法
- 就是使用tag对象来选择节点元素
- tag对象与HTML,XML的原生文档中的tag相同,即标签
#导入beautifulsoup类
from bs4 import BeautifulSoup
#传入参数,实例化这个类
soup = BeautifulSoup(html_str,'lxml')
#定位元素title
print(soup.title)
#查看获取到的结果类型:'bs4.element.Tag'类型对象,这是BeautifulSoup中一个重要的数据结构
#需要注意的是当有多个相同的标签的时候,使用此种方式只能获取第一个匹配到的节点,其他相同节点会被忽略
print(type(soup.title))
#当html中存在多个相同的节点的时候,只会提取第一个节点
print(soup.a)
提取信息的方法
#获取名称
soup.a.name
#获取属性
soup.a.attrs
#获取内容
soup.a.string
嵌套选择
- soup.tag.tag:在tag类型的基础上再次选择得到的依然是tag类型,每次返回的结果相同,就可以进行嵌套选择了
#获取title
soup.head.title
#打印获取到的title类型
type(soup.head.title)
#获取title信息
soup.head.title.string
关联选择
#获取p节点的每一个子节点
print(soup.p.contents)
print(soup.p.children)
for i,child in enumerate(soup.p.children):
print(i,child)
#获取a节点的父节点
print(soup.a.parent)
#获取a节点的祖先节点
print(soup.a.parents)
#获取a节点的兄弟节点
#获取a节点的后面一个节点
print(soup.a.next_sibling)
#获取类型
print(type(soup.a.next_sibling))
#获取a节点后面的所有节点
print(soup.a.next_siblings)
#获取所有内容
print(list(enumerate(soup.a.next_siblings)))
#获取a节点的前面所有节点
print(soup.a.previous_siblings)
②方法选择器
- find_all():获取所有符合条件的元素
- find():获取符合条件的第一个元素
- find_parent():获取符合条件的父节点
- find_parents():获取所有符合条件的祖先节点
- find_next_sibling():获取后面第一个符合条件的兄弟节点
- find_next_siblings():获取后面所有符合条件的兄弟节点
- find_previous_sibling():获取前面第一个符合条件的兄弟节点
- find_previous_siblings():获取前面所有符合条件的兄弟节点
- find_all_next():获取后面所有符合条件的节点(包括子孙节点)
- find_next():获取后面第一个符合条件的节点
- find_all_previous():获取前面所有符合条件的节点(包括子孙节点)
- find_previous():获取前面第一个符合条件的节点
③CSS选择器
- 基本用法
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
#获取class="panel-heading"的div
print(soup.select(".panel.panel-heading"))
#获取所有li节点(标签选择器)
print(soup.select("ul li"))
#获取所有li节点(类选择器)
print(soup.select(".list .element")
#获取第二个ul的li节点(id选择器)
print(soup.select("#list-2 li"))
#获取第二个ul的li节点(类选择器)
print(soup.select(".small-list li"))
#获取第二个ul节点(列表获取)
print(soup.select("ul")[1])
- 高级用法
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
#嵌套选择:先选择一个节点,再获取这个节点下面的子节点
for ul in soup.select('ul'):
print(type(ul))
print(ul.select('li'))
#获取属性
for li in soup.select("#list-2 li"):
print(type(li))
print(li.attrs)
print(li.attrs["class"])
#获取文本
for li in soup.select("#list-2 li"):
print(li.string)
for ul in soup.select("#list-2"):
print(type(ul))
print(list(ul.strings))