news 2026/4/3 6:45:21

Python 爬虫如何分析并模拟 JS 动态请求

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 爬虫如何分析并模拟 JS 动态请求

一、JS 动态请求的逆向工程核心逻辑

JS 动态请求的本质是浏览器通过 JavaScript 脚本,按照特定的规则(请求方法、参数、头信息、加密方式)向后端 API 接口发送请求,后端返回 JSON、XML 等结构化数据后,前端再进行渲染。逆向工程的核心就是还原这些请求规则,其流程可分为四步:

  1. 定位目标请求:通过浏览器开发者工具找到承载核心数据的异步请求;
  2. 分析请求参数:明确请求的 URL、方法、头信息、Query/String 参数的含义与生成规则;
  3. 破解加密逻辑:若参数存在加密(如 MD5、AES、RSA 或自定义算法),需逆向 JS 代码还原加密过程;
  4. 模拟请求发送:使用 Python 按照分析出的规则构造请求,获取数据。

这一流程的关键在于精准定位请求破解参数加密,也是逆向工程的难点所在。

二、逆向分析工具选型

完成 JS 动态请求的逆向,需要搭配合适的工具链,以下是常用工具的功能与选型建议:

工具类别推荐工具核心作用
浏览器调试工具Chrome/Firefox 开发者工具抓包、查看请求参数、调试 JS 代码
JS 代码格式化 / 反混淆Prettier、Chrome 开发者工具 Sources 面板将混淆后的 JS 代码格式化,便于阅读
加密算法验证Online Hash Calculator、CryptoJS 在线工具验证逆向出的加密算法是否正确
Python 请求库requests/httpx(同步)、aiohttp(异步)构造并发送模拟请求
JS 代码执行PyExecJS、Node.js在 Python 中执行逆向得到的 JS 加密代码

其中,Chrome 开发者工具是最基础也是最重要的工具,几乎能完成从抓包到初步 JS 分析的所有工作。

三、逆向分析实战:以某动态数据接口为例

1. 定位目标请求

以某资讯网站的动态新闻列表为例,我们需要获取其分页加载的新闻数据:

  1. 打开 Chrome 浏览器,访问目标网站,按下<font style="color:rgb(0, 0, 0);">F12</font>打开开发者工具,切换到Network面板;
  2. 勾选XHR/Fetch筛选器(只显示异步请求),滚动页面触发新闻的分页加载;
  3. 在请求列表中,找到名称包含<font style="color:rgb(0, 0, 0);">news_list</font>的请求(通常为 JSON 格式),这就是承载新闻数据的核心请求。

2. 分析请求参数

点击该请求,切换到Headers标签,可查看关键信息:

  • Request URL<font style="color:rgb(0, 0, 0);">https://example.com/api/news/list</font>(目标 API 接口);
  • Request Method:POST(请求方法);
  • Form Data/Payload:包含<font style="color:rgb(0, 0, 0);">page</font>(页码)、<font style="color:rgb(0, 0, 0);">limit</font>(每页条数)、<font style="color:rgb(0, 0, 0);">timestamp</font>(时间戳)、<font style="color:rgb(0, 0, 0);">sign</font>(签名)等参数;
  • Request Headers:包含<font style="color:rgb(0, 0, 0);">User-Agent</font><font style="color:rgb(0, 0, 0);">Referer</font><font style="color:rgb(0, 0, 0);">Token</font>等头信息。

其中,<font style="color:rgba(0, 0, 0, 0.85) !important;">page</font><font style="color:rgba(0, 0, 0, 0.85) !important;">limit</font>是普通参数,<font style="color:rgba(0, 0, 0, 0.85) !important;">timestamp</font>是当前时间戳,而<font style="color:rgba(0, 0, 0, 0.85) !important;">sign</font>是疑似加密的签名参数,这是逆向的重点。

3. 破解签名生成逻辑

要找到<font style="color:rgba(0, 0, 0, 0.85) !important;">sign</font>的生成规则,需定位对应的 JS 代码:

  1. 在开发者工具的Network面板中,右键该请求,选择Open in Sources panel,定位到发起请求的 JS 代码位置;
  2. 若代码被混淆,可使用Prettier格式化(点击 Sources 面板的<font style="color:rgb(0, 0, 0);">{}</font>按钮);
  3. 搜索<font style="color:rgb(0, 0, 0);">sign</font>关键词,找到签名生成的代码段,例如:javascript运行
functiongenerateSign(timestamp,page,limit){constsecret="abc123xyz";// 固定密钥conststr=timestamp+page+limit+secret;returnmd5(str);// MD5加密}

此时,我们就逆向出了<font style="color:rgb(0, 0, 0);">sign</font>的生成规则:将时间戳、页码、每页条数与固定密钥拼接后,进行 MD5 加密。

四、Python 模拟请求的完整实现

1. 需求定义

基于上述逆向结果,实现 Python 爬虫:

  1. 构造请求参数,生成签名;
  2. 发送 POST 请求获取新闻数据;
  3. 解析并保存数据。

2. 实现代码

importrequestsimporttimeimporthashlibimportjsonfromtypingimportDict,ListclassJSDynamicRequestCrawler:def__init__(self):# 目标API接口self.api_url="https://example.com/api/news/list"# 固定密钥(逆向得到)self.secret="abc123xyz"# 请求头(从浏览器Headers中复制)self.headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","Referer":"https://example.com/news","Content-Type":"application/json;charset=UTF-8"}defgenerate_sign(self,timestamp:str,page:int,limit:int)->str:"""根据逆向规则生成签名"""# 拼接字符串str_to_sign=f"{timestamp}{page}{limit}{self.secret}"# MD5加密md5_obj=hashlib.md5()md5_obj.update(str_to_sign.encode("utf-8"))sign=md5_obj.hexdigest()returnsigndefget_news_list(self,page:int,limit:int=10)->List[Dict]:"""获取单页新闻列表数据"""# 生成时间戳(秒级,与JS中的一致)timestamp=str(int(time.time()))# 生成签名sign=self.generate_sign(timestamp,page,limit)# 构造请求参数payload={"page":page,"limit":limit,"timestamp":timestamp,"sign":sign}try:# 发送POST请求response=requests.post(url=self.api_url,headers=self.headers,json=payload# 若接口为form-data,使用data=payload)# 验证响应状态response.raise_for_status()# 解析JSON数据data=response.json()ifdata.get("code")==200:# 假设接口返回code=200表示成功news_list=data.get("data",{}).get("list",[])print(f"成功获取第{page}页数据,共{len(news_list)}条新闻")returnnews_listelse:print(f"接口返回错误:{data.get('msg')}")return[]exceptrequests.exceptions.RequestExceptionase:print(f"请求失败:{str(e)}")return[]defsave_data(self,all_news:List[Dict],file_path:str="news_list.json"):"""保存数据到本地JSON文件"""withopen(file_path,"w",encoding="utf-8")asf:json.dump(all_news,f,ensure_ascii=False,indent=4)print(f"所有数据已保存到{file_path},共{len(all_news)}条新闻")defstart_crawl(self,max_page:int=5):"""启动爬虫,爬取多页数据"""all_news=[]forpageinrange(1,max_page+1):news_list=self.get_news_list(page)ifnotnews_list:# 若某页数据获取失败,可选择停止或继续print(f"第{page}页数据获取失败,停止爬取")breakall_news.extend(news_list)# 避免请求过快,添加短暂延迟time.sleep(1)self.save_data(all_news)if__name__=="__main__":# 初始化爬虫并启动crawler=JSDynamicRequestCrawler()crawler.start_crawl(max_page=5)

3. 代码解析

  1. 签名生成<font style="color:rgb(0, 0, 0);">generate_sign</font>方法按照逆向得到的规则,将时间戳、页码、每页条数与固定密钥拼接后进行 MD5 加密,生成签名参数;
  2. 请求发送<font style="color:rgb(0, 0, 0);">get_news_list</font>方法构造 POST 请求的参数和头信息,发送请求并解析返回的 JSON 数据;
  3. 数据采集与保存<font style="color:rgb(0, 0, 0);">start_crawl</font>方法循环爬取多页数据,<font style="color:rgb(0, 0, 0);">save_data</font>方法将数据保存到本地 JSON 文件;
  4. 反爬优化:添加了 1 秒的请求延迟,避免因请求过快被目标网站封禁 IP。

五、进阶场景与优化方案

1. 复杂加密算法的处理

若签名采用 AES、RSA 或自定义复杂算法,直接用 Python 还原可能耗时费力,可采用两种方案:

  • PyExecJS/Node.js:将逆向得到的 JS 加密代码保存为单独的文件,在 Python 中调用 JS 执行环境运行该代码,直接获取签名;
  • 逆向编译:使用 IDA Pro、Ghidra 等工具对 JS 代码进行反编译,彻底还原算法逻辑后用 Python 实现。

2. 动态 Token 的处理

若请求头中包含动态生成的 Token(如从 Cookie 或其他接口获取),需在爬虫中先请求 Token 接口,获取 Token 后再构造请求。

3. 异步优化

对于需要爬取大量数据的场景,可将同步的<font style="color:rgba(0, 0, 0, 0.85) !important;">requests</font>替换为异步的<font style="color:rgba(0, 0, 0, 0.85) !important;">aiohttp</font>,结合<font style="color:rgba(0, 0, 0, 0.85) !important;">asyncio</font>实现并发请求,提升爬取效率。

4. 反爬策略规避

  • 使用代理 IP:通过代理池为每个请求分配不同的 IP,避免 IP 被封禁;推荐亿牛云隧道代理
  • 随机化请求头:维护 User-Agent、Accept 等头信息的列表,每次请求随机选择;
  • 模拟浏览器行为:添加 Referer、Cookie 等信息,使请求更接近真实浏览器的行为。

总结

逆向工程是 Python 爬虫处理 JS 动态请求的核心能力,其本质是还原前端与后端的通信规则。从浏览器抓包定位请求,到分析参数与加密逻辑,再到用 Python 模拟请求,整个流程需要开发者具备调试 JS 代码、分析网络请求和编写爬虫的综合能力。

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

DeepSeek在线 vs 传统开发:效率提升对比

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 使用DeepSeek在线平台&#xff0c;开发一个简单的任务管理应用。要求&#xff1a;1. 自动生成前端和后端代码&#xff1b;2. 提供实时调试功能&#xff1b;3. 支持一键部署&#xf…

作者头像 李华
网站建设 2026/3/25 1:50:00

ThingsBoard-规则链中发送通知节点没有选择项

在规则链中有send notification动作节点 当我们添加该节点时&#xff0c;无法选择模板 参见官网可见&#xff0c;这儿要求的是规则链生命周期事件类模板 Rule engine lifecycle event The rule engine lifecycle event template is used to send notification about rule chain…

作者头像 李华
网站建设 2026/3/27 5:59:23

三维测距定位传感器布置:用MATLAB玩一场数学游戏

【15】MATLAB仿真 三维测距定位传感器最优布置问题&#xff0c;A优化指标&#xff0c;即最小化信息矩阵逆的迹。 三种不同约束求解。 有参考文档。 主要参考文档&#xff1a; 1. Optimal Sensor Placement for 3-D Time-of-Arrival Target Localization, in IEEE Transactions…

作者头像 李华
网站建设 2026/4/2 7:59:34

小程序毕设选题推荐:基于springboot+微信小程序的选修课管理系统的设计与实现基于微信小程序的大学选修课考勤签到系统设计与开发【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/3/28 11:01:27

JMeter实战:电商大促秒杀系统压测全流程

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个电商秒杀场景的JMeter性能测试案例库&#xff0c;包含&#xff1a;1. 典型秒杀业务流程&#xff08;库存查询→秒杀申请→支付&#xff09;的测试脚本模板&#xff1b;2. 模…

作者头像 李华
网站建设 2026/4/1 9:45:17

AI如何自动生成网络调试代码?--host参数一键搞定

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 请生成一个Python Flask web应用代码&#xff0c;要求&#xff1a;1. 创建一个简单的REST API接口返回Hello World 2. 自动添加--host参数配置使服务可被局域网访问 3. 包含完整的运…

作者头像 李华