接上文 解析数据的Beautiful Soup 模块(一)https://developer.aliyun.com/article/1617924?
find_all()——获取所有符合条件的内容
Beautiful Soup提供了一个find_all()方法,该方法可以获取所有符合条件的内容。语法格式如下:
find_all(name = None, attrs = {
}, recursive = True, text = None, limit = None, **kwargs)
• 1. name参数
name参数用来指定节点名称,指定该参数以后将返回一个可迭代对象,所有符合条件的内容均为对象中的一个元素。代码如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 创建时间 :2/6/22 10:06 PM
# 文件 :find_all(name)通过节点名称获取内容.py
# IDE :PyCharm
from bs4 import BeautifulSoup # 导入BeautifulSoup库
# 创建模拟HTML代码的字符串
html_doc = """
<html>
<head>
<title>关联获取演示</title>
<meta charset="utf-8"/>
</head>
<body>
<p class="p-1" value = "1"><a href="https://item.jd.com/12353915.html">零基础学Python</a></p>
<p class="p-2" value = "2"><a href="https://item.jd.com/12451724.html">Python从入门到项目实践</a></p>
<p class="p-3" value = "3"><a href="https://item.jd.com/12512461.html">Python项目开发案例集锦</a></p>
<div class="div-2" value = "4"><a href="https://item.jd.com/12550531.html">Python编程锦囊</a></div>
</body>
</html>
"""
# 创建一个BeautifulSoup对象,获取页面正文
soup = BeautifulSoup(html_doc, features="lxml")
print(soup.find_all(name='p')) # 打印名称为p的所有节点内容
print(type(soup.find_all(name='p'))) # 打印数据类型
程序运行结果如下:
[<p class="p-1" value="1"><a href="https://item.jd.com/12353915.html">零基础学Python</a></p>, <p class="p-2" value="2"><a href="https://item.jd.com/12451724.html">Python从入门到项目实践</a></p>, <p class="p-3" value="3"><a href="https://item.jd.com/12512461.html">Python项目开发案例集锦</a></p>]
<class 'bs4.element.ResultSet'>
说 明
bs4.element.ResultSet类型的数据与Python中的列表类似,如果想获取可迭代对象中的某条件数据可以使用切片的方式进行,如获取所有P节点中的第一个可以参考如下代码:
print(soup.find_all(name='p')[0]) # 打印所有p节点中的第一个元素
因为bs4.element.ResultSet数据中的每一个元素都是bs4.element.Tag类型,所以可以直接对某一个元素进行嵌套获取。代码如下:
print(type(soup.find_all(name='p')[0])) # 打印数据类型
print(soup.find_all(name = 'p')[0].find_all(name = 'a')) # 打印第一个p节点内的子节点a
程序运行结果如下:
<class 'bs4.element.Tag'>
[<a href="https://item.jd.com/12353915.html">零基础学Python</a>]
• 2. attrs参数
attrs参数表示通过指定属性进行数据的获取工作,在填写attrs参数时,默认情况下需要填写字典类型的参数值,但也可以通过赋值的方式填写参数。代码如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 创建时间 :2/6/22 10:48 PM
# 文件 :find_all(attrs)通过指定属性获取内容.py
# IDE :PyCharm
from bs4 import BeautifulSoup # 导入BeautifulSoup库
import re # 导入正则表达式模块
# 创建模拟HTML代码的字符串
html_doc = """
<html>
<head>
<title>关联获取演示</title>
<meta charset="utf-8"/>
</head>
<body>
<p class="p-1" value = "1"><a href="https://item.jd.com/12353915.html">零基础学Python</a></p>
<p class="p-1" value = "2"><a href="https://item.jd.com/12451724.html">Python从入门到项目实践</a></p>
<p class="p-3" value = "3"><a href="https://item.jd.com/12512461.html">Python项目开发案例集锦</a></p>
<div class="div-2" value = "4"><a href="https://item.jd.com/12550531.html">Python编程锦囊</a></div>
</body>
</html>
"""
# 创建一个BeautifulSoup对象,获取页面正文
soup = BeautifulSoup(html_doc, features="lxml")
print('指定字符串所获取的内容如下:')
print(soup.find_all(text='零基础学Python')) # 打印指定字符串所获取的内容
print('指定正则表达式对象所获取的内容如下:')
print(soup.find_all(text=re.compile('Python'))) # 打印指定正则表达式对象所获取的内容
程序运行结果如下:
字典参数结果如下:
[<p class="p-1" value="1"><a href="https://item.jd.com/12353915.html">零基础学Python</a></p>]
赋值参数结果如下:
[<p class="p-1" value="1"><a href="https://item.jd.com/12353915.html">零基础学Python</a></p>, <p class="p-1" value="2"><a href="https://item.jd.com/12451724.html">Python从入门到项目实践</a></p>]
[<p class="p-3" value="3"><a href="https://item.jd.com/12512461.html">Python项目开发案例集锦</a></p>]
• 3. text参数
指定text参数可以获取节点中的文本,该参数可以指定字符串或者正则表达式对象。代码如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 创建时间 :2/6/22 10:48 PM
# 文件 :find_all(attrs)通过指定属性获取内容.py
# IDE :PyCharm
from bs4 import BeautifulSoup # 导入BeautifulSoup库
import re # 导入正则表达式模块
# 创建模拟HTML代码的字符串
html_doc = """
<html>
<head>
<title>关联获取演示</title>
<meta charset="utf-8"/>
</head>
<body>
<p class="p-1" value = "1"><a href="https://item.jd.com/12353915.html">零基础学Python</a></p>
<p class="p-1" value = "2"><a href="https://item.jd.com/12451724.html">Python从入门到项目实践</a></p>
<p class="p-3" value = "3"><a href="https://item.jd.com/12512461.html">Python项目开发案例集锦</a></p>
<div class="div-2" value = "4"><a href="https://item.jd.com/12550531.html">Python编程锦囊</a></div>
</body>
</html>
"""
# 创建一个BeautifulSoup对象,获取页面正文
soup = BeautifulSoup(html_doc, features="lxml")
print('指定字符串所获取的内容如下:')
print(soup.find_all(text='零基础学Python')) # 打印指定字符串所获取的内容
print('指定正则表达式对象所获取的内容如下:')
print(soup.find_all(text=re.compile('Python'))) # 打印指定正则表达式对象所获取的内容
程序运行结果如下:
指定字符串所获取的内容如下:
['零基础学Python']
指定正则表达式对象所获取的内容如下:
['零基础学Python', 'Python从入门到项目实践', 'Python项目开发案例集锦', 'Python编程锦囊']
find()——获取第一个匹配的节点内容
find_all()方法可以获取所有符合条件的节点内容,而find()方法只能获取第一个匹配的节点内容。
代码如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 创建时间 :2/6/22 11:14 PM
# 文件 :find()方法获取第一个匹配的节点内容.py
# IDE :PyCharm
from bs4 import BeautifulSoup # 导入BeautifulSoup库
import re # 导入正则表达式模块
# 创建模拟HTML代码的字符串
html_doc = """
<html>
<head>
<title>关联获取演示</title>
<meta charset="utf-8"/>
</head>
<body>
<p class="p-1" value = "1"><a href="https://item.jd.com/12353915.html">零基础学Python</a></p>
<p class="p-1" value = "2"><a href="https://item.jd.com/12451724.html">Python从入门到项目实践</a></p>
<p class="p-3" value = "3"><a href="https://item.jd.com/12512461.html">Python项目开发案例集锦</a></p>
<div class="div-2" value = "4"><a href="https://item.jd.com/12550531.html">Python编程锦囊</a></div>
</body>
</html>
"""
# 创建一个BeautifulSoup对象,获取页面正文
soup = BeautifulSoup(html_doc, features="lxml")
print(soup.find(name='p')) # 打印第一个name为p的节点内容
print(soup.find(class_='p-3')) # 打印第一个class为p-3的节点内容
print(soup.find(attrs={
'value':'4'})) # 打印第一个value为4的节点内容
print(soup.find(text=re.compile('Python'))) # 打印第一个文本中包含Python的文本信息
程序运行结果如下:
<p class="p-1" value="1"><a href="https://item.jd.com/12353915.html">零基础学Python</a></p>
<p class="p-3" value="3"><a href="https://item.jd.com/12512461.html">Python项目开发案例集锦</a></p>
<div class="div-2" value="4"><a href="https://item.jd.com/12550531.html">Python编程锦囊</a></div>
零基础学Python
• 其他方法
除了find_all()和find()方法可以实现按照指定条件获取节点内容以外,Beautiful Soup模块还提供了多个其他方法,这些方法的使用方式与find_all()和find()方法相同,只是查询的范围不同,各个方法的具体说明如下:
根据条件获取节点内容的其他方法及描述
方 法 名 称 描 述
find_parent() 获取父节点内容
find_parents() 获取所有祖先节点内容
find_next_sibling() 获取后面第一个兄弟节点内容
find_previous_siblings() 获取前面第一个兄弟节点内容
find_next_siblings() 获取后面所有兄弟节点内容
find_previous_siblings() 获取前面所有兄弟节点内容
find_next() 获取当前节点的下一个符合条件的节点内容
find_all_next() 获取当前节点的下一个所有符合条件的节点内容
find_previous() 获取第一个符合条件的节点内容
find_all_previous() 获取所有符合条件的节点内容
CSS选择器
Beautiful Soup模块还提供了CSS选择器来获取节点内容,如果是Tag或者是Beautiful Soup对象都可以直接调用select()方法,然后填写指定参数即可通过CSS选择器获取到节点中的内容。
说 明
CSS选择器参考手册
https://www.w3school.com.cn/cssref/css_selectors.asp
在使用CSS选择器获取节点内容时,首先需要调用select()方法,然后为其指定字符串类型的CSS选择器。常见的CSS选择器如下:
§ 直接填写字符串类型的节点名称
§ .class:表示指定class属性值
§ #id:表示指定id属性的值
使用CSS选择器调用select()方法获取节点内容
示例代码如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 创建时间 :2/7/22 6:12 AM
# 文件 :使用CSS选择器获取节点内容.py
# IDE :PyCharm
from bs4 import BeautifulSoup # 导入BeautifulSoup库
# 创建模拟HTML代码的字符串
html_doc = """
<html>
<head>
<title>关联获取演示</title>
<meta charset="utf-8"/>
</head>
<body>
<div class="test_1" id="class_1">
<p class="p-1" value = "1"><a href="https://item.jd.com/12353915.html">零基础学Python</a></p>
<p class="p-2" value = "2"><a href="https://item.jd.com/12451724.html">Python从入门到项目实践</a></p>
<p class="p-3" value = "3"><a href="https://item.jd.com/12512461.html">Python项目开发案例集锦</a></p>
<p class="p-4" value = "4"><a href="https://item.jd.com/12550531.html">Python编程锦囊</a></p>
</div>
<div class="test_2" id="class_2">
<p class="p-5"><a href="https://item.jd.com/12185501.html">零基础学Java(全彩版)</a></p>
<p class="p-6"><a href="https://item.jd.com/12199033.html">零基础学Android(全彩版)</a></p>
<p class="p-7"><a href="https://item.jd.com/12250414.html">零基础学C语言(全彩版)</a></p>
</div>
</body>
</html>
"""
# 创建一个BeautifulSoup对象,获取页面正文
soup = BeautifulSoup(html_doc, features="lxml")
print('所有p节点内容如下:')
print(soup.select('p')) # 打印所有p节点内容
print('所有p节点中的第二个p节点内容如下:')
print(soup.select('p')[1]) # 打印所有p节点中的第二个p节点
print('逐层获取的title节点如下:')
print(soup.select('html head title')) # 打印逐层获取的title节点
print('类名为test_2所对应的节点如下:')
print(soup.select('.test_2')) # 打印类名为test_2所对应的节点
print('id值为class_1所对应的节点如下:')
print(soup.select('#class_1')) # 打印id值为class_1所对应的节点
程序运行结果如下:
所有p节点内容如下:
[<p class="p-1" value="1"><a href="https://item.jd.com/12353915.html">零基础学Python</a></p>, <p class="p-2" value="2"><a href="https://item.jd.com/12451724.html">Python从入门到项目实践</a></p>, <p class="p-3" value="3"><a href="https://item.jd.com/12512461.html">Python项目开发案例集锦</a></p>, <p class="p-4" value="4"><a href="https://item.jd.com/12550531.html">Python编程锦囊</a></p>, <p class="p-5"><a href="https://item.jd.com/12185501.html">零基础学Java(全彩版)</a></p>, <p class="p-6"><a href="https://item.jd.com/12199033.html">零基础学Android(全彩版)</a></p>, <p class="p-7"><a href="https://item.jd.com/12250414.html">零基础学C语言(全彩版)</a></p>]
所有p节点中的第二个p节点内容如下:
<p class="p-2" value="2"><a href="https://item.jd.com/12451724.html">Python从入门到项目实践</a></p>
逐层获取的title节点如下:
[<title>关联获取演示</title>]
类名为test_2所对应的节点如下:
[<div class="test_2" id="class_2">
<p class="p-5"><a href="https://item.jd.com/12185501.html">零基础学Java(全彩版)</a></p>
<p class="p-6"><a href="https://item.jd.com/12199033.html">零基础学Android(全彩版)</a></p>
<p class="p-7"><a href="https://item.jd.com/12250414.html">零基础学C语言(全彩版)</a></p>
</div>]
id值为class_1所对应的节点如下:
[<div class="test_1" id="class_1">
<p class="p-1" value="1"><a href="https://item.jd.com/12353915.html">零基础学Python</a></p>
<p class="p-2" value="2"><a href="https://item.jd.com/12451724.html">Python从入门到项目实践</a></p>
<p class="p-3" value="3"><a href="https://item.jd.com/12512461.html">Python项目开发案例集锦</a></p>
<p class="p-4" value="4"><a href="https://item.jd.com/12550531.html">Python编程锦囊</a></p>
</div>]
select()方法除了以上的基本使用方法以外,还可以实现嵌套获取、获取属性值以及获取文本等。
根据条件获取节点内容的其他方法及描述
获取节点内容的方式 描 述
soup.select(‘div[class=“test_1”]’)[0].
select(‘p’)[0] 嵌套获取class名为test_1对应的div中所有p节点中的第一个
soup.select(‘p’)[0][‘value’]
soup.select(‘p’)[0].attrs[‘value’] 获取所有p节点中第一个节点内value属性对应的值(两种方式)
soup.select(‘p’)[0].get_text()
soup.select(‘p’)[0].string 获取所有p节点中第一个节点内的文本(两种方式)
soup.select(‘p’([1:]) 获取所有p节点中第二个以后的p节点
soup.select(’.p-1, .p-5’) 获取class名为p-1与p-5对应的节点
soup.select(‘a[href]’) 获取存在href属性的所有a节点
soup.select(‘p[value = “1”]’) 获取所有属性值为value = "1"的p节点
说 明
Beautiful Soup 模块还提供了一个select_one()方法,用于获取所有符合条件节点的第一个节点,例如soup.select_one(‘a’)将获取所有a节点中的第一个a节点内容。
总 结