bs4中的BeautifulSoup.find_all函数

时间:2025-02-11 12:11:21

find_all()
find_all,顾名思义,就是查询所有符合条件的元素。给它传入一些属性或文本,就可以得到符合条件的元素,返回结果是列表类型。
语法格式:find_all( name , attrs , recursive , text , **kwargs )
各个参数含义如下:

参数 说明
name 检索标签的名称
attrs 对标签属性值的检索字符串,可标注属性检索
recursive 布尔型变量,是否对子孙全部检索,默认为True
text 标签节点中文本
**kwargs 可选参数


我们可以根据节点名来查询元素,示例如下:
我们首先我们导入bs4库,定义一个HTML实例代码,并创建beautifulsoup对象。

from bs4 import BeautifulSoup

html ="""
<html>
<head><meta charset="utf-8"><title>Python教程()</title></head>
<body>
<h1>我的第一个标题</h1>
<p class="title" name="sanmanong">Python教程学习网站
<a href="" >三码农</a>
<a href="/" >三码农</a>
<a href="https:///" >三码农</a>
</p>
<p class="list" >
<li class="element">Foo</li>
<li class="element">Bar</li>
 <li class="element">Jay</li>
</p>
</body>
</html>
"""
soup = BeautifulSoup(html,'')  #创建 beautifulsoup 对象
print(soup.find_all(name = 'p'))  # 以标签名为p查询元素
输出结果:
[<p class="title" name="sanmanong">Python教程学习网站
<a href="" id="link1">三码农</a>
<a href="/" id="link2">三码农</a>
<a href="https:///" id="link3">三码农</a>
</p>, 
<p class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</p>]

print(soup.find_all(name = 'p')[0]) # 输出查询结果列表中的第一个元素
输出结果:
<p class="title" name="sanmanong">Python教程学习网站
<a href="" id="link1">三码农</a>
<a href="/" id="link2">三码农</a>
<a href="https:///" id="link3">三码农</a>
</p>

print(type(soup.find_all(name = 'p')[0]))
输出结果:
<class ''>

这里我们调用了find_all()方法,传入name参数,其参数值为p。也就是说,我们想要查询所有p节点,返回结果是列表类型,长度为2 ,每个元素依然都是类型 。

因为都是Tag类型,所以依然可以进行嵌套查询。还是同样的文本,这里查询出所有p节点后,再继续查询其内部的a节点:

for i in soup.find_all(name = 'p'):
    print (i.find_all(name='a'))

输出结果:
[<a href="" id="link1">三码农</a>,
 <a href="/" id="link2">三码农</a>, 
 <a href="https:///" id="link3">三码农</a>
]
[]

因为此HTML中含有两个P标签,第一个p标签中含有子节点a,而第二个p标签中子节点为li,所以输出为空列表。返回结果是列表类型,列表中的每个元素依然还是Tag类型,接下来,就可以遍历每个a获取它的文本了。

for i in soup.find_all(name = 'p'):
    for x in i.find_all(name='a'):
        print(x.string) 
输出结果:
三码农
三码农
三码农


除了根据节点名查询,我们也可以传入一些属性来查询,示例如下。

print(soup.find_all(attrs = {'class':'list'}))
输出结果:
[<p class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</p>]

这里查询的时候传入的是attr 参数,参数的类型是字典类型。比如,要查询class为list的节点,可以传入 attrs = {‘class’:’list’}的查询条件,得到的结果是列表形式 ,包含的内容就是符合class为list的所有节点。在上面的例子中,符合条件的元素个数是1,所以结果是长度为1的列表。

对于一些常用的属性,比如id和class等,我们可以不用attrs来传递。比如,要查询id为list-1的节点,可以直接传人id这个参数。而对于class来说,由于class在Python里是一个关键字,所以后面需要加一个下划线,即class_=’list’。返回的结果依然还是Tag组成的列表。

print(soup.find_all(id='list-1'))
print(soup.find_all(class_='list'))


text参数可用来匹配节点的文本,传入的形式可以是字符串,可以是正则表达式对象,示例如下:
使用正则表达式需要导入re模块。

import re

print(soup.find_all(text ='Foo'))
print(soup.find_all(text=re.compile('san'))) 

输出结果:
['Foo']
['Python教程()']