【愚公系列】《Python网络爬虫从入门到精通》019-使用 BeautifulSoup 的CSS选择器
| 标题 | 详情 |
|---|---|
| 作者简介 | 愚公搬代码 |
| 头衔 | 华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。 |
| 近期荣誉 | 2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主,2024年华为云十佳博主等。 |
| 博客内容 | .NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。 |
| 欢迎 | 👍点赞、✍评论、⭐收藏 |
🚀前言
在现代网页开发和数据分析中,提取和解析网页内容是每个数据工作者必须掌握的技能。而在众多的解析工具中,BeautifulSoup凭借其直观的接口和强大的功能,成为了Python开发者的热门选择。尤其是其支持CSS选择器的特性,使得我们在定位和提取网页元素时更加灵活和高效。
本期文章将重点介绍如何使用BeautifulSoup的CSS选择器来获取网页中的内容。我们将深入探讨CSS选择器的基本概念以及在BeautifulSoup中的具体应用,包括如何使用选择器查找特定元素、提取文本和属性等。通过生动的实例演示,你将能够直观地理解如何利用CSS选择器简化数据提取的流程。
🚀一、使用 BeautifulSoup 的CSS选择器
BeautifulSoup 支持通过 CSS 选择器语法提取节点内容,使用 select() 方法实现灵活查找,适用于 Tag 或 BeautifulSoup 对象。
🔎1.基本语法
调用 select() 方法,传入 CSS 选择器字符串:
soup.select("CSS选择器语法")
🔎2.常用 CSS 选择器
| 选择器类型 | 语法示例 | 描述 |
|---|---|---|
| 标签选择器 | 'p' |
匹配所有 <p> 节点 |
| 类选择器 | '.class-name' |
匹配 class="class-name" 的节点 |
| ID 选择器 | '#id-value' |
匹配 id="id-value" 的节点 |
| 层级选择器 | 'div p' |
匹配 <div> 内嵌套的所有 <p> 节点 |
| 直接子节点 | 'div > p' |
匹配 <div> 的直接子节点 <p> |
| 组合选择器 | '.p-1, .p-5' |
匹配多个选择器的节点(逗号分隔) |
| 属性选择器 | 'p[value="1"]' |
匹配属性值符合条件的节点 |
🔎3.基础示例
示例 HTML 结构:
<body>
<div class="test 1" id="class 1">
<p class="p-1" value="1">零基础学Python</p>
<p class="p-2" value="2">Python从入门到项目实践</p>
<p class="p-3" value="3">Python项目开发案例集锦</p>
</div>
<div class="test 2" id="class 2">
<p class="p-5">零基础学Java</p>
<p class="p-6">零基础学Android</p>
</div>
</body>
🦋3.1 标签选择器
# 获取所有 <p> 标签
print(soup.select('p'))
# 输出:所有 <p> 节点的列表
🦋3.2 类选择器
# 获取 class="test 2" 的节点
print(soup.select('.test 2'))
# 注意:类名含空格时直接按字符串填写
🦋3.3 ID 选择器
# 获取 id="class 1" 的节点
print(soup.select('#class 1'))
🦋3.4 层级选择器
# 获取 <html> -> <head> -> <title> 节点
print(soup.select('html head title'))
🔎4.高级用法
🦋4.1 嵌套获取
# 获取 class="test 1" 的 div 中的第一个 <p>
div_node = soup.select('div[class="test 1"]')[0]
first_p = div_node.select('p')[0]
🦋4.2 获取属性值
# 获取第一个 <p> 的 value 属性
p_tag = soup.select('p')[0]
value1 = p_tag['value'] # 方式1:字典形式
value2 = p_tag.attrs.get('value') # 方式2:通过 attrs 属性
🦋4.3 获取文本内容
# 获取第一个 <p> 的文本
text1 = p_tag.get_text() # 方式1:包含所有子节点文本
text2 = p_tag.string # 方式2:仅当前节点文本(若子节点含标签可能返回 None)
🦋4.4 属性选择器
# 获取所有 value="1" 的 <p> 节点
p_tags = soup.select('p[value="1"]')
🦋4.5 组合选择器
# 获取 class="p-1" 和 class="p-5" 的节点
combined = soup.select('.p-1, .p-5')
🦋4.6 切片操作
# 获取所有 <p> 节点中第二个及以后的节点
p_slice = soup.select('p')[1:]
🔎5.select_one() 方法
用于获取 第一个匹配 的节点,语法与 select() 相同:
# 获取第一个 <a> 标签
first_a = soup.select_one('a')
🔎6.注意事项
-
类名含空格:
CSS 类名中的空格表示多个类(如class="test 1"包含test和1两个类),但 BeautifulSoup 允许直接按字符串匹配.test 1。 -
属性值特殊字符:
属性值含空格或特殊字符时需用引号包裹,例如div[class="test 1"]。 -
性能优化:
select()返回列表,select_one()返回单个Tag对象,后者效率更高。 -
正则表达式支持:
CSS 选择器本身不支持正则,需结合 BeautifulSoup 的其他方法(如find_all()+re.compile())。
🔎7.完整示例代码
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所对应的节点
在这里插入图片描述
🔎8.总结
| 方法 | 返回值类型 | 特点 |
|---|---|---|
select() |
list[Tag] |
返回所有匹配的节点 |
select_one() |
Tag 或 None |
返回第一个匹配节点 |
通过 CSS 选择器可快速定位复杂结构的节点,适合熟悉前端开发的用户。
- 点赞
- 收藏
- 关注作者
评论(0)