安迪Python

V1

2022/07/08阅读:18主题:默认主题

21 BeautifulSoup类的find_all()方法的name属性的用法

21 BeautifulSoup类的find_all()方法的name属性的用法

1. BeautifulSoup类的方法选择器的概括

前面我们学习了BeautifulSoup类的节点选择器和CSS选择器两种方法来提取html代码中的数据。
这两种选择方法都是通过标签或属性来进行选择。
这两种选择方法的优点是快。
缺点是在复杂的html代码中,这两种选择方法都无法精准定位到具体的元素。

【例如】

<a href="http://example.com/python" class="sisterid="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类提供的方法选择器中有许许多多的方法,如下图所示:

32_BeautifulSoup类的方法选择器
32_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参数

33_name参数
33_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="sisterhref="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. 总结

34_find_all方法
34_find_all方法

分类:

后端

标签:

Python

作者介绍

安迪Python
V1