Beautiful Soup入门
主要流程:
- 导入BeautifulSoup类
- 传递初始化参数,并初始化
- 获取实例对象,操作对象获取解析、提取数据
1.初始化Beautiful Soup对象
从bs4库导入Beautiful Soup类 实例化一个对象。
from bs4 import BeautifulSoup
soup = BeautifulSoup(markup, features)
在实例化过程中,需要给Beautiful Soup这个类传递两个参数:
第一个参数:markup
- 参数解析:被解析的HTML字符串或文件内容
- 使用方式两种
(1)使用字符串变量
#使用第一步的html_str字符串变量
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_str)
(2)使用open()函数打开文件
#假设将html_str字符串写入了index.html中
from bs4 import BeautifulSoup
soup = BeautifulSoup(open(index.html))
第二个参数,features
- 参数解释:解析器的类型
- 使用方式:
(1)指定解析器,BeautifulSoup选择指定的解析器来解析文档
#指定lxml作为解析器
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_str, 'lxml')
(2)未指定解析器,BeautifulSoup选择最默认的解析器来解析文档
#解析html_str选择最默认的解析器
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_str)
在初始化对象的时候,需要给BeautifulSoup类传递两个参数。
2.认识选择器
选择器用来查找、定位元素,并获取数据。
选择器的分类
- 节点选择器
- 方法选择器
- CSS选择器
节点选择器是获取数据的基础方法,而方法选择器和CSS选择器则是查找、定位元素的常用选择。
(1)节点选择器
i 选择元素的方法
节点选择器就是使用tag对象来选择节点元素。而tag对象与HTML、XML的原生文档中的Tag相同,即标签。
<title>The Dormouse's story</title>
<a href="http://example.com/elsie class="sister" id="link1">Elsie</a>
title和a标签及里面的内容成为Tag对象。
- 格式
获取元素:soup.tag
#soup为Beautiful Soup4的对象
返回值:节点元素
- 实例
- 选取元素只需要在Beautiful Soup对象的后面加上标签名即可,例如:soup.title
- 获取到的节点是tag对象
- 当有多个相同节点的时候,只会返回第一个节点
ii 获取信息的方法
通过选择元素的方式,我们获取到了标签的全部信息,如果我们想要提取标签中的信息,可以使用如下方式:name获取名称、attrs获取属性、string获取内容。
- 获取名称
格式:soup.tag.name
返回值:字符串
示例:
#获取a标签的名字
soup.a.name#输出结果
a
- 获取属性
格式:soup.tag.attrs
返回值:字典
示例:
#获取a标签的属性
soup.a.attrs#输出结构
{'href':'http://example.com/elsie','class':['sister'],'id':'link1'}
- 获取内容
格式:soup.tag.string
返回值:字符串
示例:
#获取a标签的内容
soup.a.string#输出结果
Elsie
iii 嵌套选择的方法
我们可以使用soup.tag获取bs4.element.Tag类型的节点,并获取他们的信息:
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>
如果提取到的节点还嵌套这其他子节点
<head><title>The Dormouse's story</title></head>
那我们可以通过下面的操作方式来获取子节点的信息。
格式:soup.tag.tag
返回值:节点元素
示例:
#获取title
print(soup.head.title)#打印获取到的title类型
print(type(soup.head.title))#获取title的信息
print(soup.head.title.string)#输出结果
<title>The Dormouse's story</title>
<class 'bs4.element.Tag'>
The Dormouse's story
soup.tag.tag:在Tag类型的基础上再次选择得到的依然是Tag类型,每次返回的结果相同,就可以进行嵌套选择了。
IV 关联选择的方法
在做选择的时候,有时候不能做到一部就选到想要的节点元素,例如示例中的第二个a节点:
<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>;
需要先选中某一个节点元素,然后以它为基准再选择它的子节点、父节点、兄弟节点等。
子节点:contents、childeren;子孙节点:descendants;父节点:parent;祖先节点:parents;兄弟节点:next_sblings、previous_sblings、previous_sblings、next_sbling。
- 子节点
格式:soup.tag.contens
返回值:列表
示例:
#获取p节点的子节点
print(soup.p.contents)#输出结果
['Once upon a time there were three little sisters; and their names were\n',<...]
格式:soup.tag.children
返回值:生成器(所以需要用for循环依次取出来)
示例:
#获取p节点的每一个子节点
print(soup.p.children)
for i, child in enumerate(soup.p.children):print(i,child)
- 父节点
格式:soup.tag.parent
返回值:节点元素
示例:
#打印选取的a节点
print(soup.a)
#获取a节点的父节点
print(soup.a.parent)#输出结果
#选取的a节点
<a class="sisier" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>
#所选a节点的父节点
<a class="story">Once upon a time there were three little sister; and their names were..
<a class="sisier" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>,
<a class="sisier" href="http://example.com/lacie" id="link2">Lacie</span></a> and
<a class="sisier" href="http://example.com/tillie" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
- 祖先节点
如果想要获取祖先节点,可以调用parents属性。
格式:soup.tag.parents
返回值:生成器
示例:
- 兄弟节点
如果想要获取同级的节点,使用sibing获取兄弟节点。
获取后面一个节点
格式:soup.tag.next_sibling
返回值:节点元素
示例:
#获取a节点的后面一个节点
print(soup.a.next_sibling)
#获取类型
print(type(soup.a.next_sibling))#输出结果
<class 'bs4.element.NavigableString'>
- 获取后面所有的节点
格式:soup.tag.next_siblings
返回值:生成器
示例:
- 获取前面一个节点
格式:soup.tag.previous_sibling
返回值:节点元素
示例:
#获取a节点的前一个节点
print(soup.a.previous_sibling)
#获取类型
print(type(soup.a.previous_sibling))#输出结果
Once upon a time there were three little sisters; and their names were <class 'bs4.element.NavigableString'>
- 获取前面的所有节点
格式:soup.tag.previous_siblings
返回值:生成器
示例:
#获取a节点前面的所有节点
print(soup.a.previous_siblings)
#获取类型
print(type(soup.a.previous_siblings))
#获取所有的内容
print(list(enumerate(soup.a.previous_siblins)))#输出结果
<generator object previous_siblings at 0x102334468>
<class 'generator'>
[(0,'Once upon a time there were three little sisters; and their names were\n')]
子节点
- soup.tag.contents
- soup.tag.children
子孙节点
- soup.tag.descendants
父节点
- soup.tag.parent
祖先节点
- soup.tag.parents
兄弟节点
- soup.tag.next_sibling
- soup.tag.next_siblings
- soup.tag.previous_sibling
- soup.tag.previous_siblings
(2)CSS选择器
- 使用CSS选择器定位元素
- 嵌套选择
- 获取属性
- 获取文本
获取元素
格式:soup.select()
CSS选择器语法
i id选择器
id选择器需要 # 来定位元素,例如:获取第一个ul节点 #list-1
<div class="panel-body"><ul class="list" id="list-1">
...
ii 类选择器
类选择器需要使用 . 来定位元素,例如:获取所有的ul.list
<div class="panel-body"><ul class="list" id="list-1"><li class="element"> Foo<li>
...<ul class="list list-small" id="list-2">
...
iii 标签选择器
标签选择器需要使用标签来进行选择,例如:获取h4:h4
<div class="panel-heading"><h4>Hello</h4>
<div>
IV 混合使用
获取第一个ul中的li节点,.panel-body #list-1 li
<div class="panel-body"><ul class="list" id="list-1"><li class="element">Foo</li><li class="element">Bar</li><li class="element">Jay</li></ul><ul class="list list-small" id="list-2"><li class="element"> Foo</li><li class="element"> Bar</li></ul>
</div>
示例:
- 获取class="panel-heading"的div
- 获取所有的li节点
- 获取第二个ul的li节点
- 获取第二个ul节点
html = '''
<div class="panel"><div class="panel-heading"><h4>Hello</h4></div><div class="panel-body"><ul class="list" id="list-1"><li class="element"> Foo</li><li class="element"> Bar</li><li class="element"> Jay</li></ul><ul class="list list-small" id="list-2"><li class="element"> Foo</li><li class="element"> Bar</li></ul></div>
</div>
...#导入Beautiful Soup类
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(".list-samll li"))#获取第二个ul的li节点 列表获取
print(soup.select("ul")[1])
CSS选择器的高级用法:
i 嵌套选择
先选择一个节点,再获取这个节点下面的子节点。
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.select("ul"))
print(type(soup.select("ul")))
for ul in soup.select("ul"):print(ul)print(type(ul))print(ul.select("li")) #这里表明可支持嵌套选择的使用
ii 获取属性
使用attrs属性来获取。
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.select("#list-2 li"))
for li in soup.select("#list-2 li"):print(type(li))print(li.attrs)print(li.attrs['class'])
iii 获取文本
使用string和strings属性来获取
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.select("#list-2 li"))
for li in soup.select("#list-2 li"):print(type(li))print(li.attrs)print(li.attrs['class'])print(soup.select("#list-2"))
for ul in soup.select("#list-2"):print(type(ul))print(ul.strings)print(list(ul.strings))
(3)方法选择器
前面的选择方法都是通过标签和属性来选择的,这种方法非常快,但是如果在比较复杂的页面中选择元素,无法精准定位到元素。
<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>;
在HTML文档中存在多个<a>标签,我们无法使用节点选择器定位到第二个、第三个<a>标签。
因此我们将采用findall()和find()方法,通过传入参数的方法来定位。
获取所有符合条件的元素 | find_all() |
获取符合条件的第一个元素 | find() |
获取所有符合条件的祖先节点 | find_parents() |
获取符合条件的父节点 | find_parent() |
获取后面所有符合条件的兄弟节点 | find_next_siblings() |
获取后面第一个符合条件的兄弟节点 | find_next_sibling() |
获取前面所有符合条件的兄弟节点 | find_previous_siblings() |
获取后面所有符合条件的节点(包括子孙节点) | find_all_next() |
获取后面第一个符合条件的节点 | find_next() |
获取前面所有符合条件的节点(包括子孙节点) | find_all_previous() |
获取前面第一个符合条件的节点 | find_previous() |
获取后面第一个符合条件的兄弟节点 | find_next_sibling() |
方法选择器中的find_all()方法
find_all(name,attrs,recursive,text, **kwargs)
- name参数
作用:查找所有名字为name的节点(tag对象)
参数形式:
- 字符串
传入字符串参数,即标签名(tag),Beautiful Soup会查找与字符串完全匹配的内容
#寻找所有soup标签
print(soup.find_all('span'))#输出结果
[<span>Elsie</span>]
- 正则表达式
传入正则表达式,Beautiful Soup会通过正则表达式的match()函数来匹配内容
#使用正则匹配以b开头的标签
import refor tag in soup.find_all(re.compile('^b")):print(tag.name)#输出结果
body
- 列表
传入列表参数,Beautifl Soup会将与列表中任一元素匹配,并返回结果。
#使用列表选择包含a和span的所有标签
print(soup.find_all(['a','span']))#输出结果
[<a class="sister" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>],
- True
True可以匹配任何值
#使用True选择文件中所有标签
for tag in soup.find_all(True):print(tag.name)#输出结果
html
head
title
...
- attrs参数
作用:查询含有接受的属性值的标签
参数形式:字典类型
#获取id为link1的标签
print(soup.find_all(attrs={id:'link1'}))#输出结果
[<a class="sister" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>]
- kwargs参数
作用:接受常用的属性参数,如id何class
参数形式:变量赋值的形式
#获取id为link1的标签
print(soup.find_all(id='link1'))#输出结果
[<a class="sister" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>]
这里直接传入id='link1',就查询到id为'link1'的节点元素了。而对class来说,它在Python中是一个关键词,需要加一个下划线,即class_='element'
#获取id为link1的标签
print(soup.find_all(class_='story'))
- text参数
作用:查询含有接收的文本的标签
参数形式:字符串
通过搜索文档中的字符串内容,来确定文件标签
#获取文本中包含Elsie内容
print(soup.find_all(text='Elsie')))#输出结果
['Elsie']
可以与其他参数混合使用来过滤tag
print(soup.find_all['a',text='Elsie'])
#搜索a标签中含有Elsie的字符串
print(soup.find_all(text='story'))
#只比对story,会发现比对不上,需要把story前面的信息补充上import re
print(soup.find_all(text=re.compile('.*?story')))
#使用text获取包含story的标签
#且必须写text
- limit参数
作用:用于限制返回结果的数量
参数形式:整数
#获取前两个a标签
print(soup.find_all('a',limit=2))
- recursive参数
作用:决定是否获取子孙节点
参数形式:布尔值,默认是True
print(soup.find_all('title'))
print(soup.find_all('title',recursive=False))
find_all()方法的使用:
- name参数用来接收tag名称,有四种形式:字符串,正则,列表和True
- attrs参数用来接收属性的键值对字典
- kwargs参数用来接收常用属性的变量赋值的形式 例如:id='link1',class="sister"
- text参数用来接收文本信息
- limit参数用来限制返回结果的数量
- recursive参数用来决定是否获取子孙节点
方法选择器中find()方法和其他方法
find()方法和find_all()方法区别在于:
- find_all()方法返回所有符合条件的元素列表,而find()方法就是返回符合条件的第一个元素
- 除了limit参数不能在find()方法中使用,find()方法的其他参数和find_all()的参数用法一样
find()方法:
作用:查找当前节点,符合条件的一个元素节点
范围:当前节点下的一个元素
- name参数
#获取a标签
print(soup.find('a'))#输出结果
<a class="sister" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>
- attrs参数
#获取class等于sister的标签
print(soup.find(attrs={'class':'sister'))#输出结果
<a class="sister" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>
- kwargs参数
#获取class等于sister的标签
print(soup.find(class_='sister'))#输出结果
<a class="sister" href="http://example.com/elsie" id="link1"><span>Elsie</span></a>
- text参数
#获取文本中包含story的标签
print(soup.find(text=re.compile('.*?story')))#输出结果
The Dormouse's story
- recursive参数
#获取文本中包含story的标签
print(soup.find('a', recursive=False))#输出结果
None
(以上为学习Python爬虫之Beautiful Soup教程的学习笔记)
Beautiful Soup入门相关推荐
- 20190221 beautiful soup 入门
beautiful soup 入门 Beautiful Soup 是 python 的一个库,最主要的功能是从网页抓取数据. Beautiful Soup 自动将输入文档转换为 Unicode 编码, ...
- Python爬虫入门(8):Beautiful Soup的用法
Python爬虫入门(1):综述 Python爬虫入门(2):爬虫基础了解 Python爬虫入门(3):Urllib库的基本使用 Python爬虫入门(4):Urllib库的高级用法 Python爬虫 ...
- 【Python爬虫】Beautiful Soup库入门
BeautifulSoup库的安装 安装 pip install beautifulsoup4 测试是否安装成功 Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2 ...
- Beautiful Soup 基础入门(实验楼学习笔记2)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 知识点 一.Beautiful Soup 简介 二.获取 HTML 页面 获取世界大学排名的页面信息 三.解析 HTM ...
- 爬虫入门之Beautiful Soup
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时 ...
- Beautiful Soup库入门
Beautiful Soup简介与安装 简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释如下: Beautiful Soup提供一些简单的py ...
- 可爱的 Python: 使用 mechanize 和 Beautiful Soup 轻松收集 Web 数据
可爱的 Python: 使用 mechanize 和 Beautiful Soup 轻松收集 Web 数据 使用 Python 工具简化 Web 站点数据的提取和组织 David Mertz, Ph. ...
- Beautiful Soup应用示例
Beautiful Soup应用示例 简介 Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库,它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式. ...
- 一文了解Beautiful Soup基本和高级用法
目录: 一.快速入门Beautiful Soup 二.定位目标内容 2.1 向下检索 2.1.1 使用标签名定位 2.1.2 .contents和.children 2.1.3 .descendant ...
最新文章
- 必学必会的nginx配置location匹配顺序总结
- 快速排序算法_基于位运算的快速排序算法
- (hdu step 7.2.1)The Euler function(欧拉函数模板题——求phi[a]到phi[b]的和)
- 用html5做一个简单网页_用Python做一个简单的翻译工具
- 30张不明觉厉的照片,看几遍终于看懂了
- 内核编程小结(引用)
- html帧内容,html将内容从一个帧移动到另一个帧
- 【原创】leetCodeOj --- Find Peak Element 解题报告
- 1010 一元多项式求导(C语言)
- 第一章ASP程序设计概述
- centos7安装tomcat9过程
- mac用什么软件测试硬盘好坏,谁说果粉不在意性能?6款macOS下硬盘测速软件介绍...
- 为交付Semi卡车做准备 特斯拉招募技术服务人员
- 调用函数----如何在主函数调用子函数
- css 怎么让图片一直旋转
- 类的设计与实现1、设计一个图形抽象类Graph,该类中有成员变量图形类型(type),维度信息(dimension,二维或三维);成员方法计算面积(computeArea); 2、设计一个接口
- Java双亲委派模型是什么、优势在哪、双亲委派模型的破坏
- Mybatis-Plus用纯注解完成一对多多对多查询
- 01. Java8-Lambada 表达式
- MapReduce任务卡在Running Job状态的多种解决方法