主要流程:

  • 导入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()方法的使用:

  1. name参数用来接收tag名称,有四种形式:字符串,正则,列表和True
  2. attrs参数用来接收属性的键值对字典
  3. kwargs参数用来接收常用属性的变量赋值的形式 例如:id='link1',class="sister"
  4. text参数用来接收文本信息
  5. limit参数用来限制返回结果的数量
  6. 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入门相关推荐

  1. 20190221 beautiful soup 入门

    beautiful soup 入门 Beautiful Soup 是 python 的一个库,最主要的功能是从网页抓取数据. Beautiful Soup 自动将输入文档转换为 Unicode 编码, ...

  2. Python爬虫入门(8):Beautiful Soup的用法

    Python爬虫入门(1):综述 Python爬虫入门(2):爬虫基础了解 Python爬虫入门(3):Urllib库的基本使用 Python爬虫入门(4):Urllib库的高级用法 Python爬虫 ...

  3. 【Python爬虫】Beautiful Soup库入门

    BeautifulSoup库的安装 安装 pip install beautifulsoup4 测试是否安装成功 Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2 ...

  4. Beautiful Soup 基础入门(实验楼学习笔记2)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 知识点 一.Beautiful Soup 简介 二.获取 HTML 页面 获取世界大学排名的页面信息 三.解析 HTM ...

  5. 爬虫入门之Beautiful Soup

    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时 ...

  6. Beautiful Soup库入门

    Beautiful Soup简介与安装 简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释如下: Beautiful Soup提供一些简单的py ...

  7. 可爱的 Python: 使用 mechanize 和 Beautiful Soup 轻松收集 Web 数据

    可爱的 Python: 使用 mechanize 和 Beautiful Soup 轻松收集 Web 数据 使用 Python 工具简化 Web 站点数据的提取和组织 David Mertz, Ph. ...

  8. Beautiful Soup应用示例

    Beautiful Soup应用示例 简介 Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库,它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式. ...

  9. 一文了解Beautiful Soup基本和高级用法

    目录: 一.快速入门Beautiful Soup 二.定位目标内容 2.1 向下检索 2.1.1 使用标签名定位 2.1.2 .contents和.children 2.1.3 .descendant ...

最新文章

  1. 必学必会的nginx配置location匹配顺序总结
  2. 快速排序算法_基于位运算的快速排序算法
  3. (hdu step 7.2.1)The Euler function(欧拉函数模板题——求phi[a]到phi[b]的和)
  4. 用html5做一个简单网页_用Python做一个简单的翻译工具
  5. 30张不明觉厉的照片,看几遍终于看懂了
  6. 内核编程小结(引用)
  7. html帧内容,html将内容从一个帧移动到另一个帧
  8. 【原创】leetCodeOj --- Find Peak Element 解题报告
  9. 1010 一元多项式求导(C语言)
  10. 第一章ASP程序设计概述
  11. centos7安装tomcat9过程
  12. mac用什么软件测试硬盘好坏,谁说果粉不在意性能?6款macOS下硬盘测速软件介绍...
  13. 为交付Semi卡车做准备 特斯拉招募技术服务人员
  14. 调用函数----如何在主函数调用子函数
  15. css 怎么让图片一直旋转
  16. 类的设计与实现1、设计一个图形抽象类Graph,该类中有成员变量图形类型(type),维度信息(dimension,二维或三维);成员方法计算面积(computeArea); 2、设计一个接口
  17. Java双亲委派模型是什么、优势在哪、双亲委派模型的破坏
  18. Mybatis-Plus用纯注解完成一对多多对多查询
  19. 01. Java8-Lambada 表达式
  20. MapReduce任务卡在Running Job状态的多种解决方法

热门文章

  1. plot3D | 三维数据绘图(1):散点图、栅格图、透视图
  2. 规格管理,及规格选项管理功能实现
  3. Windows Azure pack 升级填坑路--4 (SPF 2016 升级)
  4. thinkphp5 获取sql语句
  5. js replace替换字符串中某个指定字符
  6. 【Python入门】:程序设计3
  7. 几个常见的DP问题及解法
  8. HTML怎么统计字符,字符串中字符统计.html
  9. 图像视频去雨的几种主流方法
  10. C#RTSP通信2:RTSP语音广播+语音对讲(WinForm版本)