Python爬虫技术 第15节 CSS选择器基础

在使用Python进行网页爬取时,CSS选择器是提取HTML文档中特定元素的常用方法之一。CSS选择器基于HTML元素的结构和属性来定位和选择页面中的元素。结合Python中的BeautifulSoup库或PyQuery库等,可以非常高效地解析和筛选出你想要的数据。

CSS选择器基础

  1. 标签选择器
    使用元素名称作为选择器,如 diva

  2. 类选择器
    使用点前缀加上类名,如 .classname

  3. ID选择器
    使用井号前缀加上ID名,如 #idname

  4. 属性选择器
    可以选择具有特定属性的元素,如 [href][class="myclass"]

  5. 子元素选择器
    用于选择某个元素的直接子元素,如 ul > li

  6. 后代选择器
    用于选择某个元素的所有后代元素,如 div p(选择所有在div内的p标签)。

  7. 相邻兄弟选择器
    用于选择紧接在另一个元素后的元素,如 h1 + p

  8. 一般兄弟选择器
    用于选择同级的元素,如 h1 ~ p

  9. 组合选择器
    可以将多个选择器用逗号分隔,如 div, span

在Python中使用CSS选择器

使用BeautifulSoup

假设你有以下HTML代码:

<div id="content"><h1>My Title</h1><p class="description">This is a description.</p><ul><li>Item 1</li><li>Item 2</li></ul>
</div>

使用BeautifulSoup来解析并提取数据:

from bs4 import BeautifulSouphtml_doc = """
<div id="content"><h1>My Title</h1><p class="description">This is a description.</p><ul><li>Item 1</li><li>Item 2</li></ul>
</div>
"""soup = BeautifulSoup(html_doc, 'html.parser')# 获取标题
title = soup.select_one('h1').text
print("Title:", title)# 获取描述
description = soup.select_one('.description').text
print("Description:", description)# 获取列表项
items = [item.text for item in soup.select('li')]
print("Items:", items)
使用PyQuery

PyQuery库的使用方式更接近jQuery:

from pyquery import PyQuery as pqhtml_doc = """
<div id="content"><h1>My Title</h1><p class="description">This is a description.</p><ul><li>Item 1</li><li>Item 2</li></ul>
</div>
"""doc = pq(html_doc)# 获取标题
title = doc('h1').text()
print("Title:", title)# 获取描述
description = doc('.description').text()
print("Description:", description)# 获取列表项
items = doc('li').map(lambda i, e: pq(e).text())
print("Items:", list(items))

以上就是使用CSS选择器结合Python进行网页数据抓取的基本方法。通过这些工具,你可以更加灵活和精确地从网页中提取所需信息。

当然,我们可以处理更复杂的HTML结构、使用更多的CSS选择器以及处理可能出现的异常情况。下面是一个更详细的示例,展示如何使用BeautifulSoup和PyQuery处理一个包含更多元素和属性的HTML文档。

假设我们有以下HTML结构:

<html>
<head><title>Sample Page</title>
</head>
<body><div id="header"><h1>Welcome to Our Site</h1></div><div id="content"><section class="main"><article class="post" data-id="1"><h2>Post Title 1</h2><p>Some text here...</p><a href="/post/1" class="read-more">Read more</a></article><article class="post" data-id="2"><h2>Post Title 2</h2><p>Some other text here...</p><a href="/post/2" class="read-more">Read more</a></article></section><aside><h3>Latest Comments</h3><ul><li>User 1 commented on Post 1</li><li>User 2 commented on Post 2</li></ul></aside></div><footer><p>Copyright © 2024</p></footer>
</body>
</html>

我们将使用这个HTML结构来演示如何提取特定的帖子标题、文本和链接。

使用BeautifulSoup
from bs4 import BeautifulSouphtml_doc = """
<html>
<head><title>Sample Page</title>
</head>
<body><div id="header"><h1>Welcome to Our Site</h1></div><div id="content"><section class="main"><article class="post" data-id="1"><h2>Post Title 1</h2><p>Some text here...</p><a href="/post/1" class="read-more">Read more</a></article><article class="post" data-id="2"><h2>Post Title 2</h2><p>Some other text here...</p><a href="/post/2" class="read-more">Read more</a></article></section><aside><h3>Latest Comments</h3><ul><li>User 1 commented on Post 1</li><li>User 2 commented on Post 2</li></ul></aside></div><footer><p>Copyright © 2024</p></footer>
</body>
</html>
"""soup = BeautifulSoup(html_doc, 'html.parser')# 提取所有帖子的标题
titles = [post.h2.text for post in soup.select('.post')]
print("Titles:", titles)# 提取所有帖子的链接
links = [post.a['href'] for post in soup.select('.post .read-more') if 'href' in post.a.attrs]
print("Links:", links)# 提取第一个帖子的文本
first_post_text = soup.select_one('.post:first-of-type p').text
print("First Post Text:", first_post_text)# 检查是否有最新评论
latest_comments = soup.select_one('#content aside ul')
if latest_comments:print("Latest Comments Found!")
else:print("No latest comments found.")
使用PyQuery
from pyquery import PyQuery as pqhtml_doc = """
<html>
<!-- HTML content here -->
</html>
"""doc = pq(html_doc)# 提取所有帖子的标题
titles = doc('.post h2').map(lambda i, e: pq(e).text())
print("Titles:", list(titles))# 提取所有帖子的链接
links = doc('.post .read-more').map(lambda i, e: pq(e).attr('href'))
print("Links:", list(links))# 提取第一个帖子的文本
first_post_text = doc('.post:first-of-type p').text()
print("First Post Text:", first_post_text)# 检查是否有最新评论
latest_comments = doc('#content aside ul')
if latest_comments.length:print("Latest Comments Found!")
else:print("No latest comments found.")

以上代码展示了如何使用CSS选择器与Python库来处理和提取复杂HTML文档中的信息。注意,在实际应用中,你可能需要处理网络请求错误、HTML解析错误或页面结构不一致的情况,因此在真实环境中,你可能需要添加更多的错误检查和异常处理逻辑。

接下来,我们可以添加异常处理机制,确保在遇到网络错误、无效的HTML结构或者缺少预期元素时,程序能够优雅地处理这些情况。同时,我们还可以增强代码的健壮性,例如通过使用更具体的CSS选择器来减少误匹配的可能性,并且在处理大量数据时考虑性能优化。

以下是使用BeautifulSoup和PyQuery对上述HTML代码进行数据提取的改进版代码:

使用BeautifulSoup
from bs4 import BeautifulSoup
import requestsdef fetch_data(url):try:response = requests.get(url)response.raise_for_status()  # 如果响应状态码不是200,则抛出HTTPError异常return response.textexcept requests.RequestException as e:print(f"Error fetching URL: {url}")print(e)return Nonedef parse_html(html):if html is None:return []soup = BeautifulSoup(html, 'html.parser')posts = []for post in soup.select('.post'):try:title = post.h2.text.strip()text = post.p.text.strip()link = post.find('a', class_='read-more')['href']posts.append({'title': title,'text': text,'link': link})except AttributeError:print("Missing element in post, skipping...")continuereturn postsdef main():url = "http://example.com"html = fetch_data(url)posts = parse_html(html)print(posts)if __name__ == "__main__":main()
使用PyQuery
from pyquery import PyQuery as pq
import requestsdef fetch_data(url):try:response = requests.get(url)response.raise_for_status()return response.textexcept requests.RequestException as e:print(f"Error fetching URL: {url}")print(e)return Nonedef parse_html(html):if html is None:return []doc = pq(html)posts = []doc('.post').each(lambda i, e: posts.append({'title': pq(e)('h2').text(),'text': pq(e)('p').text(),'link': pq(e)('a.read-more').attr('href')}) if pq(e)('h2') and pq(e)('p') and pq(e)('a.read-more') else None)return [post for post in posts if post is not None]def main():url = "http://example.com"html = fetch_data(url)posts = parse_html(html)print(posts)if __name__ == "__main__":main()

在这两个示例中,我们做了如下改进:

  • 添加了网络请求函数fetch_data,它会处理网络错误和HTTP错误。
  • parse_html函数中,我们添加了对缺失元素的异常处理,避免因为某个元素不存在而导致整个程序崩溃。
  • 使用了strip()方法来去除文本中的空白字符,保证数据的整洁。
  • 在使用PyQuery时,使用了.each()方法来迭代每个.post元素,这样可以更自然地处理每个帖子的提取过程,并且通过列表推导式过滤掉任何可能为None的帖子。

这些改进使得代码更加健壮,能够在面对各种意外情况时给出适当的反馈,而不是突然崩溃。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/876019.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我的深度学习命令

安装依赖 pip install -r requirements.txt --index-url https://pypi.tuna.tsinghua.edu.cn/simple conda 环境: conda search pillow 查找可用版本 (或者pip search Pillow)查询当下虚拟环境 …

wodpress设置固定链接的方式和好处【SEO优化】

设置固定链接的好处 提高用户体验&#xff1a;固定链接使得网址更加直观和易于记忆&#xff0c;用户可以更容易地分享和访问文章。 优化SEO&#xff1a;搜索引擎更倾向于索引具有清晰结构的网址&#xff0c;固定链接有助于提高网站的SEO表现。 避免URL重复&#xff1a;固定链…

最常见的前端面试题

在前端面试中,各种面试题都会遇到,因此,今天我们整理了60+比较常见繁杂的面试题,希望这些面试题能够对你有所帮助。 当然,这些面试题的答案都不是标准答案,只是对答案做了一个简介明了的说明,希望可以快速帮助你梳理重点核心内容。 这些答案可以作为参考,但是不能作为…

需要消化的知识点

需要消化 消灭清单 如何自定义一个Interceptor拦截器&#xff1f; 后端开发可以用上的前端技巧 10个堪称神器的 Java 学习网站. 【前端胖头鱼】11 chrome高级调试技巧&#xff0c;学会效率直接提升666% 【前端胖头鱼】10个我经常逛的“小网站” 【前端劝退师lv-6】Chrome D…

【H.264】H.264详解(二)—— H264视频码流解析示例源码

文章目录 一、前言二、示例源码【1】目录结构【2】Makefile源码【3】h264parser.c源码【4】编译运行【5】源码下载地址 声明&#xff1a;此篇示例源码非原创&#xff0c;原作者雷霄骅。雷霄骅&#xff0c;中国传媒大学通信与信息系统专业博士生&#xff0c;在此向雷霄骅雷神致敬…

OpenHarmony 开发

本心、输入输出、结果 文章目录 OpenHarmony 开发前言JonathanOpenHarmony 并不是 AndroidOpenHarmony 应用迁移OpenHarmony 的开发流程OpenHarmony 开发 编辑 | 简简单单 Online zuozuo 地址 | https://blog.csdn.net/qq_15071263 如果觉得本文对你有帮助,欢迎点赞、收藏、评…

MATLAB基础应用精讲-【数模应用】二元Probit回归分析

目录 前言 知识储备 二元Logistic模型和Probit模型 Logistic模型的形式 Probit模型 优势比(OR) 准二项分布族 算法原理 数学模型 二元因变量和线性概率模型 probit和logit回归 logit和probit模型的估计和推断 稳健性检验 二元logit回归分析全流程 一、案例数…

2023IMO预选题几何第6题

锐角 △ A B C \triangle ABC △ABC 的外接圆为 ω \omega ω, 圆 I I I 与 ω \omega ω 内切于 A A A, 且与 B C BC BC 切于点 D D D. 设直线 A B AB AB, A C AC AC 分别与 I I I 交于点 P P P, Q Q Q, 点 M M M, N N N 在直线 B C BC BC 上, 满足 B B B 是 …

Git 子仓(Git Submodule)学习

Git 子仓学习 Git 子仓&#xff08;Submodule&#xff09;是 Git 提供的一种功能&#xff0c;用于在一个 Git 仓库&#xff08;称为主仓库或 superproject&#xff09;中嵌入另一个 Git 仓库&#xff08;称为子仓或 submodule&#xff09;。这种功能在管理大型项目或依赖关系较…

CeoMax总裁主题最新3.8.1破解免授权版/WordPress付费资源素材下载主题

CeoMax总裁主题最新3.8.1破解免授权版&#xff0c;一套WordPress付费资源素材下载的主题&#xff0c;感觉这是做资源站唯一一个可以和ripro媲美甚至超越的模板&#xff0c;UI很美&#xff0c;功能也很强大&#xff0c;有想学习的可下载搭建学习一下&#xff0c;仅供学习研究借鉴…

基于springsecurity的会话并发处理功能(附代码)

1. 需求 在项目中往往需要实现一个限制不同设备同时登录的功能&#xff0c;比如我只允许同一时间只有一个客户端能登录&#xff0c;而其他的已登陆的客户端会被挤出来 而springsecurity中恰好就帮我们实现好了对应的接口功能&#xff0c;我们只需要自定义配置就好 2. 结合sp…

仿学校网页

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width,initial-scale1.0"><title>学校网页</title> <style>.WebTop{backg…

誉天网络安全课程怎么样

学员服务质量保障讲师团队&#xff1a;平均5年课程交付经验&#xff0c;授课质量有保障辅导团队&#xff1a;实验论述辅导讲师&#xff0c;实验备考环境复刻&#xff0c;备考资料完善&#xff0c;及时更新就业服务&#xff1a;简历制作培训&#xff0c;面试技巧培训&#xff0c…

昇思MindSpore学习入门-轻量化数据处理

在资源条件允许的情况下&#xff0c;为了追求更高的性能&#xff0c;一般使用Pipeline模式执行数据变换Transforms。 基于Pipeline模式执行的最大特点是需要使用map方法&#xff0c;如下图中将Resize、Crop、HWC2CHW交由map调度&#xff0c;由其负责启动和执行给定的Transform…

R语言统计分析——控制流

参考资料&#xff1a;R语言实战【第2版】 语句&#xff08;statement&#xff09;是一条单独的R语言或一组复合语言&#xff08;包含在花括号{}中的一组R语言&#xff0c;使用分号分隔&#xff09; 条件&#xff08;cond&#xff09;是一条最终被解析为真&#xff08;TRUE&…

python黑马笔记

运算符&#xff1a; 算术运算符&#xff1a; 加 - 减 * 乘 / 除 // 整除 % 取余 ** 求平方 除法计算得出的结果都是小数 赋值运算符&#xff1a; 标准赋值&#xff1a; 复合赋值&#xff1a; 、 - 、 * 、 / 、// 、 ** 字符串&#xff1a; 字符串拓展内容&#xf…

护网紧急情况应对指南:Linux 应急响应手册

继上一篇&#xff1a;护网紧急情况应对指南&#xff1a;Windows版v1.2全新升级版 之后 收到小伙伴后台要Linux应急手册&#xff0c;今天给大家安排上。 《Linux应急手册》是一本为Linux系统管理员和运维工程师量身打造的实用指南&#xff0c;旨在帮助他们快速应对各种突发状况…

C++要点总结_03_条件判断语句

目录 3 条件判断语句3.1 if语句3.2 if...else...3.3 if...else if... else...3.4 三目运算符3.5. 条件运算符嵌套3.6 switch 3 条件判断语句 3.1 if语句 if(表达式){语句}: 如果if中表达式为真&#xff0c;则执行{}中的语句。反之&#xff0c;不执行。 /* if(表达式) {语句}…

在乌班图上安装SSH服务

更新包列表&#xff1a;sudo apt update 安装OpenSSH服务器软件包&#xff1a;sudo apt install openssh-server 安装完成后&#xff0c;SSH服务将自动启动。您可以通过运行以下命令来检查SSH服务的状态&#xff1a; sudo systemctl status ssh 如果SSH服务没有启动&#xff…

基于FFMPEG和SDL的音视频解码播放的实现过程与相关细节

目录 1、视频播放器原理 2、FFMPEG解码 2.1 FFMPEG库 2.2、数据类型 2.3、解码 2.3.1、接口函数 2.3.2、解码流程 3、SDL播放 3.1、接口函数 3.2、视频播放 3.3、音频播放 4、音视频的同步 4.1、获取音频的播放时间戳 4.2、获取当前视频帧时间戳 4.3、获取视…