安迪Python

V1

2022/07/09阅读:32主题:默认主题

22 BeautifulSoup类的find_all()方法的其他属性的用法

22 BeautifulSoup类的find_all()方法的其他属性的用法

本节的学习目标是find_all()方法的其它参数的用法。

1. find_all()方法的语法格式

find_all (name, attrs, kwargs, text, limit, recursive)

find_all()方法有6个参数:
【参数1】name:接收tag名称。
【参数2】attrs:参数接收属性的键值对字典。
【参数3】**kwargs:接收变量赋值形式的属性。注意class后的下划线:class_
【参数4】text:接收文本信息。
【参数5】limit:限制返回的标签数量。
【参数6】recursive:是否获取子孙节点。

2. attrs 参数

【作用】:用字典的形式传入属性和属性值,查询含有该属性值的标签。
【参数形式】:字典类型。

# 声明一个字符串变量存储HTML代码
html_str = """
<a href="http://example.com/python"  class="sister1" id="link1"><span>python学习网</span></a>        
<a href="http://example.com/java"  class="siste2r" id="link2"><span>java学习网</span></a>           
<a href="http://example.com/html" class="sister3" id="link3"><span>html学习网</span></a>   
"""

# 1. 从bs4解析库导入BeautifulSoup类用于解析数据
from bs4 import BeautifulSoup

# 2.1 BeautifulSoup类(要解析的字符串,解析器)
# 2.2 传入2个参数,实例化类得到一个BeautifulSoup对象 
bs_duixiang = BeautifulSoup(html_str, 'lxml'

# 3.1 用find_all的attrs属性获取id为link2的标签
# 3.2 attrs={'id':'link2'}的作用是查询属性为id,属性值为link2的标签
print("步骤1:查询属性为id,属性值为link2的标签:")
print(bs_duixiang.find_all(attrs={'id':'link2'}))

【终端输出】

步骤1:查询属性为id,属性值为link2的标签:
[<a class="sister" href="http://example.com/java" id="link2"><span>java学习网</span></a>]

运行代码后返回了一个a标签。
返回的a标签中id="link2"

注意attrs要传入的值是字典类型。
字典的键=属性的名称id
字典的值=属性的值link2
注意键和值都需要加引号。

3. kwargs 参数

【作用】用变量赋值的形式传入属性和属性值,查询含有该属性值的标签。
【参数形式】变量赋值的形式。

# 声明一个字符串变量存储HTML代码
html_str = """
<a href="http://example.com/python"  class="sister1" id="link1"><span>python学习网</span></a>        
<a href="http://example.com/java"  class="sister1" id="link2"><span>java学习网</span></a>           
<a href="http://example.com/html" class="sister3" id="link3"><span>html学习网</span></a>   
"""

# 1. 从bs4解析库导入BeautifulSoup类用于解析数据
from bs4 import BeautifulSoup

# 2.1 BeautifulSoup类(要解析的字符串,解析器)
# 2.2 传入2个参数,实例化类得到一个BeautifulSoup对象 
bs_duixiang = BeautifulSoup(html_str, 'lxml'

print("步骤1:使用kwargs获取class等于sister3的标签:")
print(bs_duixiang.find_all(class_='sister3'),'\n')

print("步骤2:使用attrs获取class等于sister3的标签:")
print(bs_duixiang.find_all(attrs={"class","sister3"}))

【终端输出】

步骤1:使用kwargs获取class等于sister3的标签:
[<a class="sister3" href="http://example.com/html" id="link3"><span>html学习网</span></a>] 

步骤2:使用attrs获取class等于sister3的标签:
[<a class="sister3" href="http://example.com/html" id="link3"><span>html学习网</span></a>]

【温馨提示】
attrs中使用的是class
kwargs中使用的是class_
因为对于class是Python中的一个关键字,因此这里的class后要加一个下划线,即class_='sister3'

4.text 参数

【作用】查询含的文本的标签。
【参数形式】字符串。
通过搜索文档中的字符串,来确定文本标签。

【任务】获取含有字符串“学习网”的标签。

# 声明一个字符串变量存储HTML代码
html_str = """
<a href="http://example.com/python"  class="sister" id="link1"><span>python学习网</span></a>        
<a href="http://example.com/java"  class="sister" id="link2"><span>java学习网</span></a>           
<a href="http://example.com/html" class="sister" id="link3"><span>html学习网</span></a>   
<p>python学习网</p>        
<p>java学习网</p>
<p>html学习网</p>
"""

# 1. 从bs4解析库导入BeautifulSoup类用于解析数据
from bs4 import BeautifulSoup

# 2.1 BeautifulSoup类(要解析的字符串,解析器)
# 2.2 传入2个参数,实例化类得到一个BeautifulSoup对象 
bs_duixiang = BeautifulSoup(html_str, 'lxml'

# 3. 向text中传入部分文本内容
print("步骤1:下面的代码获取到的是空列表:")
print("因为传入的text只包含“学习网”,程序会用“学习网”和所有的文本进行比对,但发现比对不上,因此返回的是空列表。")
print(bs_duixiang.find_all(text='学习网'),'\n')

# 4. 向text中传入全部文本内容
print("步骤2:使用text获取含有“java学习网”的标签:")
print("当传入的text的值'java学习网'与标签内容完全匹配,则可以返回结果:")
print(bs_duixiang.find_all(text='java学习网'),'\n')

# 5. 使用正则表达式获取含有“学习网”字符串的所有文本

# 导入正则表达式所需的re库
import re 
# re.compile('.*?学习网')使用re中的compile将正则表达式转换为模型对象
# 将模型对象作为name的参数传入find_all方法
print("步骤3:用正则表达式的.*?方法匹配含有“学习网”字符串的文本:")
print(bs_duixiang.find_all(text=re.compile(".*?学习网")),'\n')

# 6. 获取p标签中含有“学习网”字符串的文本
# re.compile('.*?学习网')使用re中的compile将正则表达式转换为模型对象
# 将模型对象作为name的参数传入find_all方法
print("步骤4:从p标签中匹配含有“学习网”字符串的节点:")
print(bs_duixiang.find_all(name='p',text=re.compile(".*?学习网")))

【终端输出】

步骤1:下面的代码获取到的是空列表:
因为传入的text只包含“学习网”,程序会用“学习网”和所有的文本进行比对,但发现比对不上,因此返回的是空列表。
[] 

步骤2:使用text获取含有“java学习网”的标签:
当传入的text的值'java学习网'与标签内容完全匹配,则可以返回结果:
['java学习网', 'java学习网'] 

步骤3:用正则表达式的.*?方法匹配含有“学习网”字符串的文本:
['python学习网', 'java学习网', 'html学习网', 'python学习网', 'java学习网', 'html学习网'] 

步骤4:从p标签中匹配含有“学习网”字符串的节点:
[<p>python学习网</p>, <p>java学习网</p>, <p>html学习网</p>]

正则表达式.*?

.*?是正则表达式中的一种模糊匹配方法,这里做简要介绍:

# 声明一个字符串变量存储HTML代码
html_str = """
<li>学号:001</li>  
<li>学号:002</li>
<li>学号:003</li>
<li>001成绩合格</li>  
<li>002成绩合格</li>
<li>003成绩优秀</li>
<li>004成绩优秀</li>
"""

# 1. 从bs4解析库导入BeautifulSoup类用于解析数据
from bs4 import BeautifulSoup

# 2.1 BeautifulSoup类(要解析的字符串,解析器)
# 2.2 传入2个参数,实例化类得到一个BeautifulSoup对象 
bs_duixiang = BeautifulSoup(html_str, 'lxml'

# 3.1 导入正则表达式所需的re库
import re 

# 3.2 re.compile('.*?')使用re中的compile将正则表达式转换为模型对象
# 3.3 将模型对象作为name的参数传入find_all方法
print("步骤1:输出都含有学号的文本内容:")
print(bs_duixiang.find_all(text=re.compile(".*?学号")),'\n')

print("步骤2:输出都含有合格的文本内容:")
print(bs_duixiang.find_all(text=re.compile(".*?合格")),'\n')

print("步骤3:输出都含有优秀的文本内容:")
print(bs_duixiang.find_all(text=re.compile(".*?优秀")))

【终端输出】

步骤1:输出都含有学号的文本内容:
['学号:001', '学号:002', '学号:003'] 

步骤2:输出都含有合格的文本内容:
['001成绩合格', '002成绩合格'] 

步骤3:输出都含有优秀的文本内容:
['003成绩优秀', '004成绩优秀']

compile [kəmˈpaɪl]:编制,编译。

<li>学号:001</li>      
<li>学号:002</li>      
<li>学号:003</li>  

上述三个标签中都有的文本内容是【学号】。
我们就可以用.*?方法获取所有含有【学号】的内容。
.*?代表不同的地方。

<li>001成绩合格</li>    
<li>002成绩合格</li>  

上述2个标签都有的文本内容是【成绩合格】。
我们就可以用.*?成绩合格.*?合格来获取所有含有【成绩合格】或【合格】的文本内容。

.*?就是正则表达式中的一种匹配方法,用法可以参考成.*?+共同的文本

5.limit 参数

【作用】用于限制返回标签的数量。
【参数形式】整数。

【任务】
在下面的HTML字符串中,li标签一共有4个。
我们现在需要提取前2个li标签,只需要将limit参数设置成2就可以。

# 声明一个字符串变量存储HTML代码
html_str = """
<li class="element">本是青灯不归客</li>
<li class="element">却因浊酒留风尘</li>
<li class="element">终是庄周梦了蝶</li>
<li class="element">你是恩赐也是劫</li>   
"""

# 1. 从bs4解析库导入BeautifulSoup类用于解析数据
from bs4 import BeautifulSoup

# 2.1 BeautifulSoup类(要解析的字符串,解析器)
# 2.2 传入2个参数,实例化类得到一个BeautifulSoup对象 
bs_duixiang = BeautifulSoup(html_str, 'lxml'

print("步骤1:设置limit参数控制提取的标签数—提取第1个li标签:")
print(bs_duixiang.find_all(name='li', limit=1),'\n')

print("步骤2:设置limit参数控制提取的标签数—提取前2个li标签:")
print(bs_duixiang.find_all(name='li', limit=2),'\n')

【终端输出】

步骤1:设置limit参数控制提取的标签数—提取第1个li标签:
[<li class="element">本是青灯不归客</li>] 

步骤2:设置limit参数控制提取的标签数—提取前2个li标签:
[<li class="element">本是青灯不归客</li>, <li class="element">却因浊酒留风尘</li>] 

使用方法是再find_all方法中传入两个参数。
第1个参数:name=li,指定要获取的标签名。
第2个参数:limit=2,指定要获取的标签数量。

6. recursive 参数

recursive[rɪˈkəːsɪv]:递归的。

【作用】决定是否获取子孙节点。
【参数形式】布尔值,默认是True。
recursive的作用是是否要递归的去查询,即是否获取子孙节点。
当值为True时默认获取子孙节点。
当值为False时默认不获取子孙节点。

# 声明一个字符串变量存储HTML代码
html_str = """
<li class="element">本是青灯不归客</li>
<li class="element">却因浊酒留风尘</li>
<li class="element">终是庄周梦了蝶</li>
<li class="element">你是恩赐也是劫</li>   
"""


# 1. 从bs4解析库导入BeautifulSoup类用于解析数据
from bs4 import BeautifulSoup

# 2.1 BeautifulSoup类(要解析的字符串,解析器)
# 2.2 传入2个参数,实例化类得到一个BeautifulSoup对象 
bs_duixiang = BeautifulSoup(html_str, 'lxml'

print("步骤1:limit和recursive联合使用—获取前2个li标签:")
print(bs_duixiang.find_all('li', limit=2, recursive=True),'\n')

print("步骤2:获取所有li标签:")
print(bs_duixiang.find_all('li', recursive=True),'\n')

print("步骤3:recursive=False限制获取li标签:")
print(bs_duixiang.find_all('li',  recursive=False))

【终端输出】

步骤1:limit和recursive联合使用—获取前2个li标签:
[<li class="element">本是青灯不归客</li>, <li class="element">却因浊酒留风尘</li>] 

步骤2:获取所有li标签:
[<li class="element">本是青灯不归客</li>, <li class="element">却因浊酒留风尘</li>, <li class="element">终是庄周梦了蝶</li>, <li class="element">你是恩赐也是劫</li>] 

步骤3:recursive=False限制获取li标签:
[]

7. 总结

35_BeautifulSoup类的find_all()方法的其他属性的用法(小)
35_BeautifulSoup类的find_all()方法的其他属性的用法(小)

分类:

后端

标签:

Python

作者介绍

安迪Python
V1