Beautiful Soup技术
一、基本过程
官方文档链接: Beautiful Soup官方文档
二、初始化Beautiful Soup对象
1、 从bs4库中导入BeautifulSoup类实例化一个对象
from bs4 import BeautifulSoup
soup = BeautifulSoup(markup,features)
1.2 其中两个参数的作用
1.2.1 markup
(1)解释
被解析的HTML字符串或文件内容
(2)两种使用方式
使用字符串变量
#使用html_str字符串变量
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_str)
使用open( )函数打开文件
#假设将html_str字符串写入index.html
from bs4 import BeautifulSoup
soup = BeautifulSoup(open(index.html))
1.2.2 features
(1) 解释
解析器的类型
(2)两种使用方式
指定解析器(BeautifulSoup选择指定的解析器来解析文档)
#指定lxml作为解析器
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_str,'lxml')
未指定解析器(BeautifulSoup选择最默认的解析器来解析文档)
#解析html_str选择最默认的解析器
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_str)
三、BeautifulSoup选择器
1、选择器分类
节点选择器(获取数据的基本方法)
方法选择器(查找、定位元素的常用选择)
CSS选择器(查找、定位元素的常用选择)
2、选择器作用
查找、定位元素、并获取数据
3、思维图
4、节点选择器
节点选择器就是使用tag对象来选择节点元素。而tag对象与HTML、XML的原生文档中的Tag相同,即标签。
<title>The Dorcument story</title>
<a href="...." id="...">Bob</a>
title和a标签里的内容成为Tag对象
#例如
print(soup.title)
4.1 格式
4.1.1 获取元素
格式:soup.tag
返回值:节点元素
html_str = """ <html><head><title>The www</title></head>
<body>
<p class="title">The www</p>
<a href="..." class="sister" id="link1">Bob</a>
<a href="..." class="sister" id="link2">Tese</a>
</body>
"""
#1、导入Beautiful Soup类
from bs4 import BeautifulSoup
#2、传入参数,实例化这个类
soup = BeautifulSoup(html_str)
#3、定位元素title
print(soup.title)
#4、查看获取到的结果的类型 获取到的元素的类型是Tag类的对象
print(type(soup.title))
#5、当html中存在多个相同的节点的时候,只会提取第一个节点
print(soup.a)
4.2 提取信息的方法
4.2.1 获取名称
格式:soup.tag.name
返回值:字符串
#例一
#获取a标签的名字
soup.a.name
#输出结果
a
4.2.2 获取属性
格式: soup.tag.attrs
返回值: 字典
#例二
#获取a标签的属性
soup.a.attrs
#输出结构
{'href':'http://exmaple.com','class':['sister'],'id':'link1'}
4.2.3 获取内容
格式:soup.tag.string
返回值:字符串
#例三
#获取a标签的内容
soup.a.string
#输出结构
Bob
4.2.4 总体样例
html_str = """ <html><head><title>The www</title></head>
<body>
<p class="title">The www</p>
<a href="..." class="sister" id="link1">Bob</a>
<a href="..." class="sister" id="link2">Tese</a>
</body>
"""
#1、导入Beautiful Soup类
from bs4 import BeautifulSoup
#2、传入参数,实例化这个类
soup = BeautifulSoup(html_str)
#3、获取a标签的名称
print(soup.a.name)
#4、查看a标签名称的类型
print(type(soup.a.name))
#5、获取a标签的属性
print(soup.a.attrs)
#6、获取a标签的值
print(soup.a.string)
4.3 嵌套选择的方法
格式:soup.tag.tag
返回值: 节点元素
html_str = """ <html><head><title>The www</title></head>
<body>
<p class="title">The www</p>
<a href="..." class="sister" id="link1">Bob</a>
<a href="..." class="sister" id="link2">Tese</a>
</body>
"""
#1、导入Beautiful Soup类
from bs4 import BeautifulSoup
#2、传入参数,实例化这个类
soup = BeautifulSoup(html_str)
#3、获取head的子节点title
print(soup.head.title)
#4、获取head的子节点title的类型
print(type(soup.head.title))
#5、获取head的子节点title的内容
print(soup.head.title.string)
4.4 关联选择的方法
在做选择的时候,有时候不能做到一步就选到想要的节点元素,需要先选中某一个节点元素,然后以他为基准再选择他的子节点、父节点、兄弟节点等。
4.4.1 子节点
格式:soup.tag.contents
返回值: 列表
格式:soup.tag.children
返回值:生成器
html_str = """ <html><head><title>The www</title></head>
<body>
<p class="title">The www</p>
<a href="..." class="sister" id="link1">Bob</a>
<a href="..." class="sister" id="link2">Tese</a>
</body>
"""
#1、导入Beautiful Soup类
from bs4 import BeautifulSoup
#2、传入参数,实例化这个类
soup = BeautifulSoup(html_str)
#3、获取p标签的子节点
print(soup.p.contents)
#4、获取p标签的子节点children
print(soup.p.children)
for i,child in enumerate(soup.p.children):
print(i,child)
4.4.2 父节点
格式:soup.tag.parent
返回值: 节点元素
html_str = """ <html><head><title>The www</title></head>
<body>
<p class="title">The www</p>
<a href="..." class="sister" id="link1">Bob</a>
<a href="..." class="sister" id="link2">Tese</a>
</body>
"""
#1、导入Beautiful Soup类
from bs4 import BeautifulSoup
#2、传入参数,实例化这个类
soup = BeautifulSoup(html_str)
#3、获取a标签的父节点 parent
print(soup.a.parent)
#4、获取a节点的祖先节点 parents
print(soup.a.parents)
print(list(enumerate(soup.a.parents)))
4.4.3 兄弟节点
(1)获取后面一个节点
格式:soup.tag.next_sibling
返回值: 节点元素
(2)获取后面所有的节点
格式:soup.tag.next_siblings
返回值: 生成器
(3)获取前面一个节点
格式:soup.tag.previous_sibling
返回值:节点元素
(4)获取前面所有的节点
格式:soup.tag.previous_siblings
返回值: 生成器
html_str = """ <html><head><title>The www</title></head>
<body>
<p class="title">The www</p>
<a href="..." class="sister" id="link1">Bob</a>
<a href="..." class="sister" id="link2">Tese</a>
</body>
"""
#1、导入Beautiful Soup类
from bs4 import BeautifulSoup
#2、传入参数,实例化这个类
soup = BeautifulSoup(html_str)
#3、获取a节点的兄弟节点 next_sibling
print(soup.a.next_sibling)
#4、获取a节点的所有兄弟节点 next_siblings
print(soup.a.next_siblings)
print(list(enumerate(soup.a.next_siblings)))
#5、获取a节点的前面一个节点 previous_sibling
print(soup.a.previous_sibling)
#6、获取a节点的前面的所有节点,previous_siblings
print(soup.a.previous_siblings)
print(list(enumerate(soup.a.previous_siblings)))
5、CSS选择器
主要分支和内容
5.1 获取元素
使用CSS选择器,只需要调用select( )方法,并结合CSS选择器语法就可以定位元素的位置。
格式:soup.select( )
5.2 CSS选择器语法
5.2.1 id选择器
id选择器需要使用#来定位元素,例如:获取第一个ul节点 #list-1
5.2.2 类选择器
类选择器需要使用 . 来定位元素,例如:获取所有的ul . list
5.2.3 标签选择器
标签选择器需要使用标签来进行选择,例如:获取h4
5.2.4 混合使用
获取第一个ul中的li节点 例如:.panel-body #list-1 li
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>
'''
#1、导入Beautiful Soup类
from bs4 import BeautifulSoup
#2、传入参数,实例化这个类
soup = BeautifulSoup(html)
#3、获取class="panel-heading"的div
print(soup.select(".panel .panel-heading"))
#4、获取所有的li节点 标签选择器
print(soup.select("ul li"))
#5、获取所有的li节点 类选择器
print(soup.select(".list .element"))
#6、获取第二个ul的li节点 id选择器
print(soup.select("#list-2 li"))
#7、获取第二个ul的li节点 类选择器
print(soup.select(".list-small li"))
#8、获取第二个ul节点 列表获取
print(soup.select("ul")[1])
5.3 CSS选择器高级用法
5.3.1 嵌套选择
先选择一个节点,再获取这个节点下面的子节点
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>
'''
#1、导入Beautiful Soup类
from bs4 import BeautifulSoup
#2、传入参数,实例化这个类
soup = BeautifulSoup(html)
#3、获取ul节点
print(soup.select("ul"))
#4、查看ul节点的类型
print(type(soup.select("ul")))
for ul in soup.select("ul"):
print(ul)
print(type(ul))
print(ul.select("li"))
5.3.2 获取属性
css选择器获取属性的方法和节点选择器获取属性的方法一样,使用attrs属性来获取。
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>
'''
#1、导入Beautiful Soup类
from bs4 import BeautifulSoup
#2、传入参数,实例化这个类
soup = BeautifulSoup(html)
#3、获取li节点
print(soup.select("#list-2 li"))
for li in soup.select("#list-2 li"):
print(type(li))
print(li.attrs)
print(li.attrs['class'])
5.3.3 获取文本
css选择器获取文本的方法和节点选择器获取文本的方法一样,使用string和strings属性来获取
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>
'''
#1、导入Beautiful Soup类
from bs4 import BeautifulSoup
#2、传入参数,实例化这个类
soup = BeautifulSoup(html)
#3、获取li节点
print(soup.select("#list-2 li"))
for li in soup.select("#list-2 li"):
print(type(li))
print(li.string)
#4、获取ul节点
print(soup.select("#list-2"))
for ul in soup.select("#list-2"):
print(type(ul))
print(ul.strings)
print(list(ul.strings))
6、方法选择器
6.1 find_all( )方法
6.1.1 作用及范围
6.1.1.1 作用
用于搜索当前节点的所有符合条件的节点
6.1.1.2 范围
当前节点下的所有节点,如果没有指定当前节点,则进行全文的搜索
6.1.1.3 用法
find_all(name,attrs,recursive,text,**kwargs)
6.1.2 name参数
6.1.2.1 作用
查找所有名字为name的节点(tag对象)
6.1.2.2 参数形式
(1)字符串
传入一个字符串参数,即标签名(tag),Beautiful Soup会查找与字符串内容完全匹配的内容
#寻找所有span标签
print(soup.find_all(name="span"))
(2)正则表达式
传入正则表达式,Beautiful Soup会通过正则表达式的match( ) 函数来匹配内容
import re
for tag in soup.find_all(re.compile('^b')):
print(tag.name)
(3) 列表
传入列表参数,Beautiful Soup会与列表中任一元素匹配,并返回结果
#使用列表选择包含a和span的所有标签
print(soup.find_all(['a','span']))
(4) True
True可以匹配任何值
#使用True选择文件中所有标签
for tag in soup.find_all(True):
print(tag.name)
6.1.2.3 样例
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">
<span>Foo</span>
</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>
'''
#1、导入Beautiful Soup类
from bs4 import BeautifulSoup
#2、传入参数,实例化这个类
soup = BeautifulSoup(html)
#3、获取span标签 字符串
print(soup.find_all(name="span"))
#4、获取span标签 正则表达式 模型对象
import re
reg = re.compile('^sp')
print(soup.find_all(name=reg))
#5、获取a和span标签列表
print(soup.find_all(name=['a','span']))
#6、True的用法 递归的获取所有的标签
print(soup.find_all(name=True))
6.1.3 attrs参数
6.1.3.1 作用
查询含有接受的属性值的标签
6.1.3.2 参数形式
字典类型
#获取id为link1的标签
print(soup.find_all(attrs={id:'link1'}))
6.1.4 kwargs参数
6.1.4.1 作用
接收常用的属性参数,如id 和 class
6.1.4.2 参数形式
变量赋值的形式
#获取id为link1的标签
print(soup.find_all(id='link1'))
6.1.5 text参数
6.1.5.1 作用
查询含有接收的文本的标签
6.1.5.2 参数形式
字符串
通过搜索文档中的字符串内容,来确定文件标签
#获取文本中包含Elsie内容
print(soup.find_all(text='Elsie'))
也可以与其他参数混合使用来过滤tag
#获取文本中包含Elsie内容的标签
print(soup.find_all('a',text='Elsie'))
6.1.6 limit参数
6.1.6.1 作用
用于限制返回结果的数量
6.1.6.2 参数形式
整数
#获取前两个a标签
print(soup.find_all('a',limit=2))
6.1.7 recursive参数
6.1.7.1 作用
决定是否获取子孙节点
6.1.7.2 参数形式
布尔值,默认是True
print(soup.find_all('title',recursive=False))
6.1.8 样例
name参数用来接收tag名称,有四种形式:字符串,正则。列表和True
attrs参数用来接收属性的键值对字典
kwargs参数用来接收常用属性的变量赋值的形式 例如:id = ‘link1’, class_ = “sister”
text参数用来接收文本信息
limit参数用来限制返回结果的数量
recursive参数用来决定是否获取子孙节点
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">
<span>Foo</span>
</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>
'''
#1、导入Beautiful Soup类
from bs4 import BeautifulSoup
#2、传入参数,实例化这个类
soup = BeautifulSoup(html)
#3、使用attrs获取id为link1的标签
print(soup.find_all(attrs={'id':'link1'}))
#4、使用kwargs获取class等于sister的标签
print(soup.find_all(class='sister'))
#5、使用text获取包含story的标签
import re
print(soup.find_all(name='b',text=re.compile('.*?story')))
#6、使用limit限制p标签的查询只获取第一个
print(soup.find_all(name='p',limit=1))
#7、使用recursive限制第一个p标签的查询
print(soup.find_all('p',limit=1,recursive=False))
6.2 find()方法
6.2.1 作用
find( ) 方法和find_all( ) 方法类似,都是在文档中查找所需要的信息
6.2.2 区别
find_all( ) 方法返回所有符合条件的元素列表(查找当前节点下,符合条件的所有节点)
find( ) 方法就是返回符合条件的第一个元素(查找当前节点下,符合条件的第一个节点)
6.2.3 可供使用参数
name, attrs, text, kwargs, recursive (没有limit参数)