安迪Python
2022/07/08阅读:174主题:默认主题
21 BeautifulSoup类的find_all()方法的name属性的用法
21 BeautifulSoup类的find_all()方法的name属性的用法
1. BeautifulSoup类的方法选择器的概括
前面我们学习了BeautifulSoup类的节点选择器和CSS选择器两种方法来提取html代码中的数据。
这两种选择方法都是通过标签或属性来进行选择。
这两种选择方法的优点是快。
缺点是在复杂的html代码中,这两种选择方法都无法精准定位到具体的元素。
【例如】
<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>
上述代码中出现了3个a
标签。
通过标签或属性我们无法精准定位到第2个或第3个a
标签。
如果我们要提取第2个或第3个a
标签里的内容我们可以利用BeautifulSoup类中的find_all或find方法,通过向方法传入参数的方式来进行精准定位。
BeautifulSoup类提供的方法选择器中有许许多多的方法,如下图所示:

【温馨提示】
前面第1个符合条件的兄弟节点和前面第1个符合条件的节点是有区别的。
前1个兄弟节点和前1个节点有时候可能是同一个节点。
上图中,我们可以看到总共有12种选择方法。
这12种选择方法他们的用法都是一样的,只不过提取数据的范围会不同。
这里我们重点学习find_all及find方法。
我们将这两个方法学会以后,其它方法在你需要的时候直接去调用就行。
他们参数的位置以及参数的方法都和find_all及find方法都是一样的。
2. find_all()方法的作用及范围
find_all:查找全部。
【作用】搜索当前节点下所有符合条件的节点。
【范围】当前节点下的所有节点。如果没有指定当前节点,则进行全文检索。
【温馨提示】
使用find_all方法通常需要指定当前节点。
3. find_all()方法的语法格式
find_all (name, attrs, recursive, text, **kwargs)
find_all()方法有5个参数:
参数1.name
参数2.attrs
参数3.recursive
参数4.text
参数5.**kwargs
4. find_all方法的name参数

name参数的作用:查找所有名字为name
的标签。
例如:name='span'
将标签名span作为参数传入find_all方法中,BeautifulSoup会查找与标签名span完全匹配的内容。
name参数一共有4种形式:
1.字符串
2.正则表达式
3.列表
4.True
4.1. name参数=标签名=字符串
当name参数传入的是字符串类型即标签名称的时候,BeautifulSoup会查找与标签名完全匹配的内容。
# 声明一个字符串变量存储HTML代码
html_str = """
<html>
<head>
<title>学习网址</title>
</head>
<body>
<p class="story">
这里有3个网址,他们分别是:
<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>
<p>
<li class="element">本是青灯不归客</li>
<li class="element">却因浊酒留风尘</li>
<li class="element">终是庄周梦了蝶</li>
<li class="element">你是恩赐也是劫</li>
</p>
</body>
</html>
"""
# 1. 从bs4解析库导入BeautifulSoup类用于解析数据
from bs4 import BeautifulSoup
# 2.1 BeautifulSoup类(要解析的字符串,解析器)
# 2.2 传入2个参数,实例化类得到一个BeautifulSoup对象
bs_duixiang = BeautifulSoup(html_str, 'lxml')
# 3. 使用find_all 方法,name参数传入的字符串
print("步骤1:bs对象.find_all(name=标签名)——获取标签名为span的所有节点:")
print(bs_duixiang.find_all(name="span"),'\n')
# 4. 使用find_all 方法,name参数传入的字符串
print("步骤2:bs对象.find_all(name=标签名)——获取标签名为li的所有节点:")
print(bs_duixiang.find_all(name="li"))
【终端输出】
步骤1:bs对象.find_all(name=标签名)——获取标签名为span的所有节点:
[<span>python学习网</span>, <span>java学习网</span>, <span>html学习网</span>]
步骤2:bs对象.find_all(name=标签名)——获取标签名为li的所有节点:
[<li class="element">本是青灯不归客</li>, <li class="element">却因浊酒留风尘</li>, <li class="element">终是庄周梦了蝶</li>, <li class="element">你是恩赐也是劫</li>]
当我们在代码中传入一个标签名为span
的参数, BeautifulSoup会根据传递的标签名去查找当前节点下的标签名为span的节点。
当name="span"
时,代码就会去html_str中查找标签名为span
的对象。
当name="li"
时,代码就会去html_str中查找标签名为li
的对象。
注意:这里的标签名是加引号的,是字符串形式。
4.2. name=正则表达式='^b'
正则表达式是一章需要单独学习的内容,相关知识需要详细的学习,这里仅做了解。
当name参数传入的是正则表达式的时候,BeautifulSoup会通过正则表达式中的match()
函数来匹配相关内容。 '^b'
即匹配以字母b开头的节点。
^
符合的输入方法
英文输入法状态下,按住shift
+字母键盘上方的数字键6
就能输入^
。
代码演示
compile [kəmˈpaɪl]:编译器。
model [ˈmɒdl]:模型。
target [ˈtɑːɡɪt]:对象。
# 声明一个字符串变量存储HTML代码
html_str = """
<html>
<head>
<title>学习网址</title>
</head>
<body>
<p class="story">
这里有3个网址连接,他们分别是:
<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>
<p>
<li class="element">本是青灯不归客</li>
<li class="element">却因浊酒留风尘</li>
<li class="element">终是庄周梦了蝶</li>
<li class="element">你是恩赐也是劫</li>
</p>
</body>
</html>
"""
# 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将正则表达式转换为模型对象
model_target1 = re.compile('^ti')
model_target2 = re.compile('^sp')
# 3.3. 使用find_all方法,name参数传入的值是正则表达式的模型对象
print("步骤1:输出以字母ti开头的节点:")
print(bs_duixiang.find_all(name=model_target1),'\n')
print("步骤2:输出以字母sp开头的节点:")
print(bs_duixiang.find_all(name=model_target2))
【终端输出】
步骤1:输出以字母ti开头的节点:
[<title>学习网址</title>]
步骤2:输出以字母sp开头的节点:
[<span>python学习网</span>, <span>java学习网</span>, <span>html学习网</span>]
正则表达式和for循环的综合运用
# 声明一个字符串变量存储HTML代码
html_str = """
<html>
<head>
<title>学习网址</title>
</head>
<body>
<p class="story">
这里有3个网址连接,他们分别是:
<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>
<p>
<li class="element">本是青灯不归客</li>
<li class="element">却因浊酒留风尘</li>
<li class="element">终是庄周梦了蝶</li>
<li class="element">你是恩赐也是劫</li>
</p>
</body>
</html>
"""
# 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
# re.compile('^sp')使用re中的compile将正则表达式转换为模型对象
# 将模型对象作为name的参数传入find_all方法
print("步骤1:输出以字母sp开头的节点:")
for tag in bs_duixiang.find_all(re.compile('^sp')):
print(tag)
print('\n')
print("步骤2:输出以字母l开头的节点名称:")
for tag in bs_duixiang.find_all(re.compile('^l')):
print(tag.name)
【终端输出】
步骤1:输出以字母sp开头的节点:
<span>python学习网</span>
<span>java学习网</span>
<span>html学习网</span>
步骤2:输出以字母l开头的节点名称:
li
li
li
li
因为html_str字符串中有4个li
节点,因此输出的以字母l
开头的节点名称有4个。
4.3. 列表
当name参数传入的是列表,BeautifulSoup会将html文档与列表中的任一元素匹配,然后将结果组合成列表进行返回。
# 声明一个字符串变量存储HTML代码
html_str = """
<html>
<head>
<title>学习网址</title>
</head>
<body>
<p class="story">
这里有3个网址连接,他们分别是:
<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>
<p>
<li class="element">本是青灯不归客</li>
<li class="element">却因浊酒留风尘</li>
<li class="element">终是庄周梦了蝶</li>
<li class="element">你是恩赐也是劫</li>
</p>
</body>
</html>
"""
# 1. 从bs4解析库导入BeautifulSoup类用于解析数据
from bs4 import BeautifulSoup
# 2.1 BeautifulSoup类(要解析的字符串,解析器)
# 2.2 传入2个参数,实例化类得到一个BeautifulSoup对象
bs_duixiang = BeautifulSoup(html_str, 'lxml')
# 使用find_all 方法,传入的参数值为列表
print(bs_duixiang.find_all(['title','span']))
【终端输出】
[<title>学习网址</title>, <span>python学习网</span>, <span>java学习网</span>, <span>html学习网</span>]
传入的列表['title','span']
中有2个参数,里面包含了我们想提取的标签名称,title
和'span
。
运行代码后,返回的结果是一个列表,结果包含title
和'span
标签。
4.4. True
True
可以匹配任何值,当name参数传入的是True
,输出的是html文档中的所有节点。
当name参数传入的是True
,find_all方法会递归获取所有标签。
# 声明一个字符串变量存储HTML代码
html_str = """
<html>
<head>
<title>学习网址</title>
</head>
<body>
<p class="story">
这里有3个网址连接,他们分别是:
<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>
<p>
<li class="element">本是青灯不归客</li>
<li class="element">却因浊酒留风尘</li>
<li class="element">终是庄周梦了蝶</li>
<li class="element">你是恩赐也是劫</li>
</p>
</body>
</html>
"""
# 1. 从bs4解析库导入BeautifulSoup类用于解析数据
from bs4 import BeautifulSoup
# 2.1 BeautifulSoup类(要解析的字符串,解析器)
# 2.2 传入2个参数,实例化类得到一个BeautifulSoup对象
bs_duixiang = BeautifulSoup(html_str, 'lxml')
print(list(enumerate(bs_duixiang.find_all(name=True))))
【终端输出】
[(0, <html>
<head>
<title>学习网址</title>
</head>
<body>
<p class="story">
这里有3个网址连接,他们分别是:
<a class="sister" href="http://example.com/python" id="link1"><span>python学习网</span></a>
<a class="sister" href="http://example.com/java" id="link2"><span>java学习网</span></a>
<a class="sister" href="http://example.com/html" id="link3"><span>html学习网</span></a>
</p>
<p>
</p><li class="element">本是青灯不归客</li>
<li class="element">却因浊酒留风尘</li>
<li class="element">终是庄周梦了蝶</li>
<li class="element">你是恩赐也是劫</li>
</body>
</html>),
(1, <head>
<title>学习网址</title>
</head>),
(2, <title>学习网址</title>),
(3, <body>
<p class="story">
这里有3个网址连接,他们分别是:
<a class="sister" href="http://example.com/python" id="link1"><span>python学习网</span></a>
<a class="sister" href="http://example.com/java" id="link2"><span>java学习网</span></a>
<a class="sister" href="http://example.com/html" id="link3"><span>html学习网</span></a>
</p>
<p>
</p><li class="element">本是青灯不归客</li>
<li class="element">却因浊酒留风尘</li>
<li class="element">终是庄周梦了蝶</li>
<li class="element">你是恩赐也是劫</li>
</body>),
(4, <p class="story">
这里有3个网址连接,他们分别是:
<a class="sister" href="http://example.com/python" id="link1"><span>python学习网</span></a>
<a class="sister" href="http://example.com/java" id="link2"><span>java学习网</span></a>
<a class="sister" href="http://example.com/html" id="link3"><span>html学习网</span></a>
</p>),
(5, <a class="sister" href="http://example.com/python" id="link1"><span>python学习网</span></a>),
(6, <span>python学习网</span>),
(7, <a class="sister" href="http://example.com/java" id="link2"><span>java学习网</span></a>),
(8, <span>java学习网</span>),
(9, <a class="sister" href="http://example.com/html" id="link3"><span>html学习网</span></a>),
(10, <span>html学习网</span>),
(11, <p></p>),
(12, <li class="element">本是青灯不归客</li>),
(13, <li class="element">却因浊酒留风尘</li>),
(14, <li class="element">终是庄周梦了蝶</li>),
(15, <li class="element">你是恩赐也是劫</li>)]
运行代码后得到内容和html文档是有区别的。
得到的是一个列表。
列表中的共有15个元素:
第1个:一整个HTML节点。
第2个:head节点。
第3个:title节点。
第4个:body节点。
第5个:第1个p节点。
第6个:第1个a节点。
第7个:第1个span节点。
第8个:第2个a节点。
第9个:第2个span节点。
第10个:第3个a节点。
第11个:第3个span节点。
第12个:第2个p节点。
第13个:第1个li节点。
第14个:第2个li节点。
第15个:第3个li节点。
第13个:第4个li节点。
name= True和for循环的综合运用
# 声明一个字符串变量存储HTML代码
html_str = """
<html>
<head>
<title>学习网址</title>
</head>
<body>
<p class="story">
这里有3个网址连接,他们分别是:
<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>
<p>
<li class="element">本是青灯不归客</li>
<li class="element">却因浊酒留风尘</li>
<li class="element">终是庄周梦了蝶</li>
<li class="element">你是恩赐也是劫</li>
</p>
</body>
</html>
"""
# 1. 从bs4解析库导入BeautifulSoup类用于解析数据
from bs4 import BeautifulSoup
# 2.1 BeautifulSoup类(要解析的字符串,解析器)
# 2.2 传入2个参数,实例化类得到一个BeautifulSoup对象
bs_duixiang = BeautifulSoup(html_str, 'lxml')
print("输出所有节点的名称:")
for i , tag in enumerate(bs_duixiang.find_all(name=True)) :
print(i,tag.name)
【终端输出】
输出所有节点的名称:
0 html
1 head
2 title
3 body
4 p
5 a
6 span
7 a
8 span
9 a
10 span
11 p
12 li
13 li
14 li
15 li
enumerate [ɪˈnjuːməreɪt]:枚举、列举。
for i , tag in enumerate(bs_duixiang.find_all(name=True)) :
print(i, tag.name)
在for循环中增加的i
的作用是输出时元素前会增加一个序号。
print(list(enumerate(bs_duixiang.find_all(name=True))))
list(enumerate())
的作用:输出列表的元素前会增加一个序号。
5. 总结

作者介绍