基于requests_html的python爬虫
前言:今天介绍一个相对性能更高的爬虫库requests_html,会不会感觉和requests有点联系?是的。为什么开始不直接介绍呢?因为我觉得requests是最基本入门的东西,并且在学习过程中也能学到很多东西。我的python老师在介绍这两个库时是直接一起讲的,然后我就很混乱,各自特点以及用法都分不清楚。不是说老师讲得不好啊,老师是高手,是我太菜了~.~
requests_html库也是requests
的作者开发的,是对requests
、PyQuery
、lxml
、beautifulsoup4
等库的二次封装。它将请求和解析功能集成在一起,使用起来更加方便。此外,requests_html
还支持异步请求,能够提高爬虫的效率。但是,在某些复杂场景下,它的使用不如单独使用requests
和BeautifulSoup
灵活。
首先第一步当然是安装requests_html库啦,前面的文章有介绍,自行查阅
发送请求
from requests_html import HTMLSession #从requests_html模块中导入了HTMLSession类(封装了 requests)
session=HTMLSession() #创建HTMLSession的实例(一个会话对象),用于发送HTTP请求
r=session.get('https://blog.csdn.net/2402_88126487?type=blog') #发起GET请求,r是Response对象(同requests)
if r.status_code!=200:raise Exception('error')
print(r.text) #返回的是响应的原始HTML文本
print(r.html.html) #r.html是requests_html库提供的功能(包含一些额外的处理,比如自动解码)
#r.html是一个HTML对象,对响应的HTML内容进行了解析和封装,r.html.html是将解析后的HTML对象转换为字符串形式,便于查看和操作
requests_html为html对象提供了许多方便的属性和方法
r.html.html #返回解析后的HTML内容的字符串形式
r.html.url #返回实际请求的URL,可能与初始请求的URL不同(例如经过重定向后)
r.html.base_url #返回页面的基准URL
r.html.links #返回页面中所有链接的集合
r.html.absolute_links #返回页面中所有绝对链接的集合(完整的URL)
r.html.encoding #查看以及更改页面的编码格式
r.html.render() #渲染页面以执行JavaScript
#如果请求的网页包含动态加载的数据,那么在提取数据之前需调用r.html.render(),确保页面上的JavaScript代码被执行,从而加载所有动态内容
#使用需下载包(前面的文章介绍过了),
r.html.find()
r.html.xpath() #这两个方法将在下面介绍
request-html支持CSS选择器和XPATH两种语法来选取HTML元素
r.html.find(selector,first=False)
使用 CSS 选择器查找页面中的元素,如果 first=True
,则只返回第一个匹配的Element
对象;否则返回所有匹配的Element
对象的列表,使用方法有点类似于soup.find(),但不能直接在 find
方法中指定如class等的参数,selector参数说明如下:
r.html.find('div') #查找所有标签为<div>的元素
r.html.find('div.article-list') #查找所有标签为<div>类名为article-list的元素
r.html.find('div#abc123') #查找id为abc123的<div>标签的元素
Element
对象是requests_html
库中用于表示HTML元素的对象,有如下属性和方法
element.text #获取元素的文本内容
element.attrs['href'] #通过element.attrs字典(包含了元素的所有属性)来访问元素的属性
element.find() #查找当前元素的子元素
element.html #获取元素的HTML内容
现在我们来尝试打印主包博客首页每篇文章的标题
from requests_html import HTMLSession
session=HTMLSession()
r=session.get('https://blog.csdn.net/2402_88126487?type=blog')
if r.status_code!=200:raise Exception('error')
titles=r.html.find('article.blog-list-box') #titles是列表,不能继续.find
for title in titles:title=title.find('h4', first=True)print(title.text)
r.html.xpath(xpath,first=False)
使用 XPath 表达式查找页面中的元素,如果 first=True
,则只返回第一个匹配的元素;否则返回所有匹配的元素(element对象),xpath参数说明如下
r.html.xpath('//div') #查找所有标签为<div>的元素
r.html.xpath("//div[@class='example']") #查找所有<div>的class="example"的元素
r.html.xpath("//a[@href='https://example.com']")查找所有href=https://example.com的<a>元素
给大家分享一下如何快速得到xpath
找到要提取的元素,右键,点击“复制”,点击“复制完整的XPath”
我们复制前两篇文章标题的xpath,如下,可以发现除了article后面的数字,其它都完全相同,并且数字代表篇数,那么我们可以通过改变数字获取所有标题的h4标签(为什么会想到这个呢?因为可以发现标题的存储都十分有规律)
/html/body/div[2]/div/div[1]/div/div/div/div/div/div[2]/div/div[2]/div[1]/div[2]/div/article[1]/a/div[2]/div[1]/div[1]/h4
/html/body/div[2]/div/div[1]/div/div/div/div/div/div[2]/div/div[2]/div[1]/div[2]/div/article[2]/a/div[2]/div[1]/div[1]/h4
再写代码之前还要补充下:从浏览器开发者工具中复制的 XPath 是基于当前页面的完整结构生成的绝对路径。若网页中的某些内容是通过 JavaScript 动态生成的,这个XPath就会失效。解决方法是调用r.html.render()
来渲染动态内容。博客首页开始有些地方是没有展示的,当我们在底部继续往下拉后才显示出来,但是url没有改变,说明这个网页是动态加载的
代码如下
from requests_html import HTMLSession
session=HTMLSession()
r=session.get('https://blog.csdn.net/2402_88126487?type=blog')
if r.status_code!=200:raise Exception('error')
r.html.render()
for n in range(1,11):title=r.html.xpath(f'/html/body/div[2]/div/div[1]/div/div/div/div/div/div[2]/div/div[2]/div[1]/div[2]/div/article[{n}]/a/div[2]/div[1]/div[1]/h4')if title==[]:continueprint(title[0].text)
展示如下,不知道为什么STL那篇没法显示,但我单独查找article[7]是可以搜索到的,可能是页面加载时间过长了吧
关闭会话
完成请求后,建议关闭会话对象,释放资源(虽然不关不会报错,但这可以避免潜在的资源泄漏)
session.close()
爬取百度
现在,我们来解决一下之前遗留的问题(入门那一篇),当然用上一篇的抓包动态加载也可以,但requests_html支持JavaScript真的方便很多哦
代码如下
from requests_html import HTMLSession
url='https://www.baidu.com/'
session=HTMLSession()
r=session.get(url)
r.html.render()
titles=r.html.find('ul#hotsearch-content-wrapper',first=True).find('li')
for title in titles:data=title.find('span')print(title.find('a',first=True).attrs['href'],data[0].text,data[1].text)
展示如下
至此,一代新星即将升起,你已经“出师”了
最后,再给大家分享个网站——博客园,主包之前查信息有看到过这个网站,不过没去细看,最近发现里面真的有好多好棒的IT(Information Technology)专业信息文章,并且网页都是渲染过的,视觉体验好棒
相关文章:

基于requests_html的python爬虫
前言:今天介绍一个相对性能更高的爬虫库requests_html,会不会感觉和requests有点联系?是的。为什么开始不直接介绍呢?因为我觉得requests是最基本入门的东西,并且在学习过程中也能学到很多东西。我的python老师在介绍这…...
循环神经网络:捕捉序列数据中的时间信息
目录 循环神经网络:捕捉序列数据中的时间信息 一、循环神经网络的基本概念 (一)RNN 的基本结构 (二)RNN 的工作原理 (三)RNN 的优势 (四)RNN 的局限性 二、循环神…...
第35周Zookkeeper+Dubbo 面试题精讲
面试题精讲 一、算法面试答题思路 理解思路的重要性:算法面试比基础面试更复杂,需先想清楚思路,与面试官沟通确认题目条件(如数据范围、是否包含负数/零等),这有助于理清解题思路并展示技术实力。变量命名清晰:算法中变量命名要明确含义和范围,避免使用模糊的变量名,…...
聊聊更新中断和更新事件那些事儿
最近在研究一些系统和设备的更新机制,发现更新中断和更新事件这两个概念很有意思,也容易让人混淆,今天就来和大家好好探讨一下。 一、更新事件 (一)定义与原理 更新事件,简单来说,是当出现某…...

STM32:按键模块 传感器模块 以及 相关C语言知识(详细讲解)
目录 按键 传感器模块 C语言知识 C语言数据类型 C语言宏定义 C语言typedef C语言结构体 C语言枚举 按键 常见的输入设备,按下导通,松手断开 按键抖动:由于按键内部使用的是机械式弹簧片来进行通断的,所以在按下和松手的瞬…...

C++23 std::mdspan:多维数组处理新利器
文章目录 引言C23简介std::mdspan的定义与特点定义特点 std::mdspan的优势零成本抽象的多维数据访问减少内存开销提高代码灵活性 std::mdspan的应用场景科学计算图形学 相关提案示例代码使用动态扩展使用静态和动态扩展 总结 引言 在C的发展历程中,每一个新版本都带…...

基于高德MCP2.0的智能旅游攻略系统设计与实现
前言:旅游规划的技术革命 在数字化旅游时代,MCP2.0(Map-based Collaborative Planning)系统代表着旅游攻略技术的最新演进。作为对1.0版本的全面升级,MCP2.0通过深度整合高德地图API和智能算法,实现了从静…...

【时时三省】(C语言基础)用函数实现模块化程序设计
山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 为什么要用函数? 已经能够编写一些简单的C程序,但是如果程序的功能比较多,规模比较大,把所有的程序代码都写在一个主函数(main函数)中&#x…...

Flink流处理:实时计算URL访问量TopN(基于时间窗口)
目录 代码分析 背景知识拓展 代码调优 1. 性能优化 1.1 使用 KeyedStream 和 ProcessWindowFunction 替代 windowAll 1.2 使用 ReduceFunction 优化聚合 2. 功能扩展 2.1 支持动态窗口大小 2.2 支持多维度统计 2.3 支持持久化存储 3. 代码可读性 3.1 提取公共逻辑 …...
初识函数------了解函数的定义、函数的参数、函数的返回值、说明文档的书写、函数的嵌套使用、变量的作用域(全局变量与局部变量)
文章目录 一、什么是函数?二、函数定义与调用2.1 基本语法2.2 示例演示 三、函数参数详解3.1 位置参数3.2 默认参数3.3 可变参数3.4 关键字参数 四、返回值与文档说明4.1 返回多个值4.2 编写文档字符串 五、函数嵌套与作用域5.1 嵌套函数示例5.2 变量作用域5.3 glob…...
java collection集合特点知识点详解
在 Java 中,Collection 是所有集合类的根接口,它定义了一组对象的基本操作。Java 集合框架提供了丰富的实现类(如List、Set、Queue),具有以下核心特点: 一、统一的接口设计 1. 核心接口层次 Collection …...
ngx_http_realip_module 模块概述
一、使用场景 日志记录 记录真实客户端 IP 而非反向代理的 IP,有助于流量分析和安全审计。访问控制 基于真实 IP 实现防火墙规则(allow/deny)或限流,而非误将上游 IP 视为客户端。GeoIP、WAF、限速等功能 模块化的上游真实 IP 支…...
自定义CString类与MFC CString类接口对比
接口对比表格 功能分类 你的 CString 接口 MFC CString 接口(ANSI) 一致性 差异说明 构造函数 CString() CString(const char*) CString(char) CString(const CString&) CString() CString(LPCSTR) CString(TCHAR) CString(const CString&…...

华为OD机试真题——考勤信息(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
2025 A卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…...

Go语言测试用例的执行与分析
在软件开发过程中,测试用例是确保代码质量的关键环节。Go语言作为一种现代的编程语言,它内置了强大的测试框架,可以帮助开发者轻松编写和执行测试用例。本文将介绍如何在 Go 语言中编写、执行测试用例,并对测试结果进行分析。 ## …...
vue3 vite 路由
如路由是这种格式 http://localhost:7058/admin/product/brand路由配置如下 import { createRouter, createWebHistory } from vue-router import HomeView from ../views/HomeView.vue import NProgress from nprogress; import nprogress/nprogress.css; import {errorRour…...

MyBatis:动态SQL
文章目录 动态SQLif标签trim标签where标签set标签foreach标签include标签和sql标签 Mybatis动态SQL的官方文档: https://mybatis.net.cn/dynamic-sql.html 动态SQL 动态SQL是 MyBatis的强大特性之一,如果是使用JDBC根据不同条件拼接sql很麻烦,例如拼接…...

游戏引擎学习第280天:精简化的流式实体sim
回顾并为今天的内容做铺垫 今天的任务是让之前关于实体存储方式的改动真正运行起来。我们现在希望让实体系统变得更加真实和实用,能够支撑我们游戏实际所需的功能。这就要求我们对它进行更合理的实现和调试。 昨天我们基本让代码编译通过了,但实际上还…...
femap许可与多用户共享
随着电磁仿真技术的发展,Femap作为一款领先的工具,在多个领域中发挥着不可替代的作用。然而,对于许多团队和企业来说,如何高效、经济地管理和使用Femap许可证成为了一个亟待解决的问题。本文将探讨Femap许可与多用户共享的概念、优…...

王树森推荐系统公开课 排序03:预估分数融合
融合预估分数 p c l i c k ⋅ p l i k e p_{click} \cdot p_{like} pclick⋅plike 有实际意义,等于在曝光中点赞的概率。 p c l i c k ⋅ p c o l l e c t p_{click} \cdot p_{collect} pclick⋅pcollect 同理。 按多种排名做 ensemble sort。 某电商的融…...

网络I/O学习-poll(三)
一、为什么要用Poll 由于select参数太多,较于复杂,调用起来较为麻烦;poll对其进行了优化 二、poll机制 poll也是一个系统调用,每次调用都会将所有客户端的fd拷贝到内核空间,然后进行轮询,判断IO是否就绪…...

k8s(12) — 版本控制和滚动更新(金丝雀部署理念)
金丝雀部署简介: 1、基本概念 金丝雀部署是一种软件开发中的渐进式发布策略,其核心思想是通过将新版本应用逐步发布给一小部分用户(即 “金丝雀” 用户),在真实环境中验证功能稳定性和性能表现,再逐步扩大发…...
【git config --global alias | Git分支操作效率提升实践指南】
git config --global alias | Git分支操作效率提升实践指南 背景与痛点分析 在现代软件开发团队中,Git分支管理是日常工作的重要组成部分。特别是在规范的开发流程中,我们经常会遇到类似 feature/user-management、bugfix/login-issue 或 per/cny/dev …...
chrome源码中WeakPtr 跨线程使用详解:原理、风险与最佳实践
base::WeakPtr 在 Chromium 中 不能安全地跨线程使用。这是一个很关键的点,下面详细解释原因及正确用法。 🔍原理与使用 ✅ 先说答案: base::WeakPtr 本质上是**线程绑定(thread-affine)**的。不能在多个线程之间创建…...
【Go】从0开始学习Go
文章目录 从0开始学习Go0 与C对比1 代码框架1.1 helloworld式代码示例1.2 主体代码元素(核心三部分)1.3 其他 2 与C/C区别3 有用的小工具4 注意事项 从0开始学习Go 0 与C对比 特性CGo编译型语言需要编译为机器码直接编译为二进制可执行文件静态类型类型…...
Windows 安装显卡驱动
1.第一步:打开Nvidia 官网驱动下载页面 2.第二步:选择相关信息, 玩游戏选择,GeForce Game Ready ,创意设计、摄影直播 选择 NVIDIA Studio 驱动程序 (NVIDIA Studio Driver - WHQL.) 2.第三步࿱…...
模块与包的导入
一、导入官方库 我们复盘下学习python的逻辑,所谓学习python就是学习python常见的基础语法学习你所处理任务需要用到的第三方库 类别典型库解决的问题学习门槛基础工具os、sys、json操作系统交互、序列化数据(如读写 JSON 文件)低科学计算n…...

Google设置app-ads.txt
问题: 应用上架后admob后台显示应用广告投放量受限,需要设置app-ads.txt才行。 如何解决: 官方教程: 看了下感觉不难,创建一个txt,将第二条的代码复制进行就得到app-ads.txt了。 然后就是要把这个txt放到哪才可以…...

docker安装rockerMQ
参考Docker部署RocketMQ5.x (单机部署配置参数详解不使用docker-compose直接部署)_rocketmq不推荐用docker部署-CSDN博客 镜像拉取 镜像地址: https://hub.docker.com/r/apache/rocketmq/tags 我在部署的时候最新发行版是5.1.0可以根据需求自行选择一个5.x的版本&a…...

交叉引用、多个参考文献插入、跨文献插入word/wps中之【插入[1-3]、连续文献】
我们在写论文时,需要插入大量参考文献。 有时,一句话需要引用多个文献,如:[1-3]或者[1,3,4]这种形式多个文献插入、跨文献插入。 在上一篇文章中,我们提到可以直接打“-”或者“,”,但是word导出…...