news 2026/4/18 5:01:08

Python 爬虫实战:如何优雅地处理带有 JWT 认证的接口提交

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 爬虫实战:如何优雅地处理带有 JWT 认证的接口提交

目录

    • Python 爬虫实战:如何优雅地处理带有 JWT 认证的接口提交
    • 第一章:当爬虫遇上“隐形门卫”——JWT 认证机制解析
      • 1.1 什么是 JWT?
      • 1.2 为什么爬虫需要特别关注 JWT?
      • 1.3 JWT 的“双刃剑”对爬虫的影响
    • 第二章:Python 实战:模拟登录与 Token 获取
      • 2.1 准备工作:分析目标 API
      • 2.2 编写获取 Token 的 Python 代码
      • 2.3 常见登录陷阱与应对
    • 第三章:带着“通行证”出发:在请求中注入 JWT
      • 3.1 构造带认证的 Header
      • 3.2 封装为通用爬虫类(Class)
    • 第四章:进阶技巧与安全防御视角
      • 4.1 应对高级防御:Token 存储与刷新
      • 4.2 从防御者角度看 JWT 爬虫
      • 4.3 总结

专栏导读
  • 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手
  • 🏳️‍🌈 个人博客主页:请点击——> 个人的博客主页 求收藏
  • 🏳️‍🌈 Github主页:请点击——> Github主页 求Star⭐
  • 🏳️‍🌈 知乎主页:请点击——> 知乎主页 求关注
  • 🏳️‍🌈 CSDN博客主页:请点击——> CSDN的博客主页 求关注
  • 👍 该系列文章专栏:请点击——>Python办公自动化专栏 求订阅
  • 🕷 此外还有爬虫专栏:请点击——>Python爬虫基础专栏 求订阅
  • 📕 此外还有python基础专栏:请点击——>Python基础学习专栏 求订阅
  • 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
  • ❤️ 欢迎各位佬关注! ❤️

Python 爬虫实战:如何优雅地处理带有 JWT 认证的接口提交

第一章:当爬虫遇上“隐形门卫”——JWT 认证机制解析

在传统的网页爬虫开发中,我们习惯于直接请求目标 URL,解析 HTML,提取数据。然而,随着现代 Web 应用架构的演进,前后端分离(SPA)已成为主流。这意味着数据不再是直接嵌入在 HTML 中,而是通过 API 接口以 JSON 格式交互。为了保护这些接口的安全,开发者往往会设置一道“门卫”——JWT (JSON Web Token)

对于爬虫工程师而言,理解 JWT 的工作原理是绕过这道门卫的关键。

点击 投票 获取Python办公自动化高清书籍
点击 投票 获取Python办公自动化高清书籍
点击 投票 获取Python办公自动化高清书籍
(Excel Python:飞速搞定数据分析与处理 (【瑞士】费利克斯·朱姆斯坦) )

1.1 什么是 JWT?

JWT 是一种开放标准(RFC 7519),用于在网络应用环境间传递声明。它将用户信息加密成一个 Token,通常由三部分组成:

  1. Header(头部):包含令牌类型和签名算法(如 HMAC SHA256 或 RSA)。
  2. Payload(负载):包含用户身份信息(如用户ID、过期时间)。
  3. Signature(签名):这是安全性的核心。服务器使用 Header 和 Payload,配合只有服务器知道的密钥(Secret)进行签名。

1.2 为什么爬虫需要特别关注 JWT?

在传统的 Session/Cookie 机制中,服务器会在客户端保留一个 Session ID,爬虫只需保持 Cookie 即可。但在 JWT 模式下,服务器是无状态的。客户端(浏览器)在登录成功后,会收到一个长字符串(Token),之后的每一次请求,都必须在 HTTP Header 中携带这个 Token(通常是Authorization: Bearer <token>)。

如果我们的爬虫忽略了这个机制,直接去请求需要登录的接口,服务器会直接返回401 Unauthorized,就像被门卫直接拦在门外一样。

1.3 JWT 的“双刃剑”对爬虫的影响

  • 优势:Token 可以跨域使用,且不需要服务器查询数据库验证 Session,速度极快。
  • 挑战:Token 有过期时间(exp),一旦过期必须重新获取。此外,为了安全,很多应用会使用 Refresh Token 机制,或者对 Token 进行加密处理(JWE),这大大增加了爬虫模拟的复杂度。

第二章:Python 实战:模拟登录与 Token 获取

在掌握了理论基础后,我们需要动手操作。本章节将使用 Python 的requests库,演示如何从零开始获取一个 JWT Token。

2.1 准备工作:分析目标 API

假设我们要爬取一个名为 “DataHub” 的虚构平台数据。首先,我们需要打开浏览器的开发者工具(F12),切换到 Network 面板,进行一次真实的登录操作。

观察结果

  • 请求 URLhttps://api.datahub.com/v1/auth/login
  • 请求方法POST
  • 请求体(Payload){"username": "your_user", "password": "your_password"}

2.2 编写获取 Token 的 Python 代码

利用requests库,我们可以轻松模拟这个过程。

importrequests# 1. 定义登录接口和凭证login_url="https://api.datahub.com/v1/auth/login"headers={"Content-Type":"application/json","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"}payload={"username":"your_username","password":"your_password"}# 2. 发送登录请求try:response=requests.post(login_url,json=payload,headers=headers)# 检查响应状态ifresponse.status_code==200:# 3. 解析响应数据data=response.json()# 假设服务器返回的数据结构如下:# {"code": 0, "msg": "success", "data": {"access_token": "eyJhbGciOiJIUz...", "refresh_token": "..."}}access_token=data.get("data",{}).get("access_token")ifaccess_token:print(f"成功获取 Token:{access_token[:20]}...")else:print("响应中未找到 access_token 字段")else:print(f"登录失败,状态码:{response.status_code}, 原因:{response.text}")exceptExceptionase:print(f"发生错误:{e}")

2.3 常见登录陷阱与应对

  • 验证码(Captcha):如果登录接口带有图形验证码,简单的requests就失效了。此时,你需要引入 OCR 库(如ddddocr)或者接入打码平台。
  • CSRF Token:部分老式网站在登录时会要求携带一个隐藏的 CSRF Token。你需要先请求一次登录页,解析 HTML 获取该 Token,再发起登录。
  • 加密参数:现在的前端为了安全,往往会将密码进行 JS 加密(如 RSA 或 AES)。你需要使用 Python 的pycryptodome库复现该加密逻辑,或者直接使用PyExecJS执行原生 JS 代码。

第三章:带着“通行证”出发:在请求中注入 JWT

拿到 Token 后,万里长征走完了一半。现在我们需要将这个 Token 应用到后续的数据提交和获取请求中。

3.1 构造带认证的 Header

这是最关键的一步。绝大多数 API 规范要求将 Token 放入 HTTP Header 的Authorization字段中,格式通常为Bearer <token>

importrequests# 假设我们已经获取到了 tokenaccess_token="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."# 1. 构造请求头headers={"Authorization":f"Bearer{access_token}","Content-Type":"application/json","Accept":"application/json"}# 2. 访问需要认证的接口(例如:提交数据或获取用户信息)target_url="https://api.datahub.com/v1/user/profile"# 或者是一个 POST 提交接口# target_url = "https://api.datahub.com/v1/data/submit"try:# 发起 GET 请求获取数据resp=requests.get(target_url,headers=headers)ifresp.status_code==200:print("数据获取成功:",resp.json())elifresp.status_code==401:print("错误:Token 失效或未提供,请重新登录!")elifresp.status_code==403:print("错误:Token 有效,但权限不足(Scope 不够)!")else:print(f"未知错误:{resp.status_code}")exceptExceptionase:print(f"请求异常:{e}")

3.2 封装为通用爬虫类(Class)

为了代码的复用性和可维护性,建议将 Token 管理封装成一个类:

classJWTCrawler:def__init__(self,username,password):self.username=username self.password=password self.base_url="https://api.datahub.com"self.token=Noneself.session=requests.Session()# 使用 Session 保持连接deflogin(self):"""登录并获取 Token"""url=f"{self.base_url}/v1/auth/login"payload={"username":self.username,"password":self.password}try:resp=self.session.post(url,json=payload)self.token=resp.json().get("data",{}).get("access_token")returnTrueifself.tokenelseFalseexceptExceptionase:print(f"登录失败:{e}")returnFalsedefrequest(self,method,endpoint,**kwargs):"""通用请求方法,自动注入 Token"""ifnotself.token:ifnotself.login():raiseException("无法获取有效 Token")url=f"{self.base_url}{endpoint}"headers=kwargs.get("headers",{})headers["Authorization"]=f"Bearer{self.token}"kwargs["headers"]=headers response=self.session.request(method,url,**kwargs)# 处理 Token 过期的情况(通常状态码为 401)ifresponse.status_code==401:print("Token 已过期,尝试重新登录...")ifself.login():# 重新发起请求headers["Authorization"]=f"Bearer{self.token}"kwargs["headers"]=headers response=self.session.request(method,url,**kwargs)else:raiseException("刷新 Token 失败")returnresponse# 使用示例# crawler = JWTCrawler("user", "pass")# resp = crawler.request("GET", "/v1/data/list")# print(resp.json())

第四章:进阶技巧与安全防御视角

作为一名资深的爬虫开发者,不仅要学会攻,还要懂防。了解 JWT 的弱点,能帮助我们应对更复杂的反爬机制;了解防御策略,则能帮助我们开发更健壮的应用。

4.1 应对高级防御:Token 存储与刷新

  • Refresh Token 机制:为了安全,很多应用不会给 Access Token 很长的过期时间(如 15 分钟)。此时,服务器会同时返回一个 Refresh Token(有效期 7 天)。当 Access Token 过期时,客户端应使用 Refresh Token 去请求/refresh接口换取新的 Access Token。

    • 爬虫应对:在JWTCrawler类中增加refresh_token字段,并在request方法捕获 401 错误后,优先尝试调用刷新接口,而不是直接重新登录(避免频繁触发登录风控)。
  • HttpOnly Cookie:有些应用虽然使用了 JWT,但为了防止 XSS 攻击,会将 Token 存储在HttpOnly的 Cookie 中,而不是 JS 可读的localStorage。这种情况下,requests直接读取 JS 变量是行不通的。

    • 爬虫应对:使用SeleniumPlaywright等浏览器自动化工具。先用浏览器自动化工具完成登录,然后通过get_cookies()提取 Token,再转交给requests使用。

4.2 从防御者角度看 JWT 爬虫

如果你是 API 的开发者,该如何防止他人通过模拟 JWT 爬取数据?

  1. 签名算法选择:严禁使用None算法。推荐使用HS256(对称)或RS256(非对称)。如果密钥泄露,攻击者可以伪造任何用户的 Token。
  2. 增加黑名单机制:JWT 的特性是“一旦签发,无法撤回”。为了解决这个问题,可以在 Redis 中维护一个 Token 黑名单(用户注销或修改密码时将旧 Token 加入黑名单)。
  3. IP 与 User-Agent 绑定:在 Payload 中加入 IP 或设备指纹信息,并在验证时检查。如果一个 Token 突然在不同的 IP 下使用,判定为异常。
  4. 动态 Token(混淆 Token):像 WeChat 这样的应用,会使用动态 Token,每次请求后 Token 都会变化,或者使用加密的二进制格式,大大增加了逆向难度。

4.3 总结

处理带有 JWT 认证的 Python 爬虫,核心在于模拟“客户端行为”。这不仅仅是发送 HTTP 请求,更是一个对认证流程的逆向工程。

  • 初级阶段:手动抓包,硬编码 Token。
  • 中级阶段:编写登录脚本,自动获取并管理 Token。
  • 高级阶段:处理 Token 过期刷新、应对加密参数、结合浏览器自动化工具解决复杂渲染问题。

随着反爬技术的升级,单纯的 HTTP 请求越来越难以满足需求,将requests的高效与playwright的渲染能力相结合,是未来爬虫开发的必然趋势。


互动环节:
你在爬取带有 JWT 认证的网站时,遇到过最棘手的问题是什么?是复杂的加密参数,还是动态变化的 Token?欢迎在评论区分享你的经历,我们一起探讨解决方案!

结尾
  • 希望对初学者有帮助;致力于办公自动化的小小程序员一枚
  • 希望能得到大家的【❤️一个免费关注❤️】感谢!
  • 求个 🤞 关注 🤞 +❤️ 喜欢 ❤️ +👍 收藏 👍
  • 此外还有办公自动化专栏,欢迎大家订阅:Python办公自动化专栏
  • 此外还有爬虫专栏,欢迎大家订阅:Python爬虫基础专栏
  • 此外还有Python基础专栏,欢迎大家订阅:Python基础学习专栏

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 8:06:32

PixelMatch驱动的视觉回归测试:低误报率与高速UI检测优化方案

‌一、视觉回归测试的技术演进‌ 随着前端技术复杂度的提升&#xff0c;传统基于DOM的测试已无法满足界面验证需求。视觉回归测试通过比对渲染结果图像&#xff0c;成为检测UI偏差的核心手段。2013年出现的PixelMatch算法&#xff0c;以其轻量级&#xff08;仅4KB&#xff09;…

作者头像 李华
网站建设 2026/4/18 7:40:58

打卡信奥刷题(2714)用C++实现信奥题 P3243 [HNOI2015] 菜肴制作

P3243 [HNOI2015] 菜肴制作 题目描述 知名美食家小 A 被邀请至 ATM 大酒店&#xff0c;为其品评菜肴。ATM 酒店为小 A 准备了 nnn 道菜肴&#xff0c;酒店按照为菜肴预估的质量从高到低给予 111 到 nnn 的顺序编号&#xff0c;预估质量最高的菜肴编号为 111。 由于菜肴之间口味…

作者头像 李华
网站建设 2026/4/18 7:35:25

打卡信奥刷题(2715)用C++实现信奥题 P3361 Cool loves maids

P3361 Cool loves maids 题目背景 Cool 非常喜欢妹子&#xff0c;以至于 Cool 在百度上有一个非常神奇的 ID 【雾】。 题目描述 Cool 现在搞清楚了女生宿舍的地形。女生宿舍是由很多栋楼构成的&#xff0c;它们可以被抽象成 202020\times 202020 的方格。 Cool 的妹子们所处的地…

作者头像 李华
网站建设 2026/4/18 4:15:22

STM32 - 滴答定时器 - 2

一、滴答定时器&#xff08;SysTick&#xff09;概述 SysTick 是 Cortex-M 内核&#xff08;如 STM32F103 用的 Cortex-M3&#xff09;自带的 24 位递减定时器&#xff0c;属于内核级外设&#xff0c;而非 STM32 片上外设。核心用途&#xff1a; 裸机开发&#xff1a;实现微秒…

作者头像 李华
网站建设 2026/4/18 9:43:53

基于STM32电表交流电压电流有功无功视在功率因数频率设计24-035(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

基于STM32电表交流电压电流有功无功视在功率因数频率设计24-035(设计源文件万字报告讲解)&#xff08;支持资料、图片参考_相关定制&#xff09;_文章底部可以扫码24-035、STM32智能交流电压电流有功功率功率因数频率无功功率视在功率演示视频&#xff08;复制到浏览器打开&…

作者头像 李华