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教程()']