Js逆向分析+Python爬虫结合

JS逆向分析+Python爬虫结合

特别声明📢:本教程只用于教学,大家在使用爬虫过程中需要遵守相关法律法规,否则后果自负!!!

  • 完整代码地址Github:https://github.com/ziyifast/ziyifast-code_instruction/tree/main/python-demo/spider-demo/spider-js
  • 大家如果觉得还不错的话,欢迎star⭐️哦

1 概念

有时我们通过Python爬虫爬取数据会发现服务器返回的是密文数据,我们拿到密文之后,需要对它进行解密才能转换为可用数据。

  • 前端对服务器返回的密文数据是通过JS来进行解密的,这时我们就需要分析并找到前端解密的代码,应用到我们的爬虫,达到爬虫抓取并解密数据的效果。
  • 总结:JS逆向分析,大致就是我们 ①分析前端JS代码 + ②通过JS代码解密服务器返回的密文数据。

2 JS逆向分析

以烯牛平台数据为例,我们登录平台,访问目前国内最新赛道,服务发现服务器返回的都是加密后数据,这时我们就需要使用XHR断点,一步步进行逆向分析。
在这里插入图片描述

  • 平台链接:https://www.xiniudata.com/industry/newest?from=data

思路分析 & 定位JS文件

在这里插入图片描述

  1. 可以看到服务器返回回来的数据在d字段中,这种命名太过常见,因此我们不能通过关键字定位搜索对应的js代码。
  2. 因为返回的是json数据,前端js肯定会进行解码,所以我们可以搜索与JSON.parse()有关的方法,找到对应解码位置。
  3. f12打开开发者工具,抓请求包,找到请求发起的js文件,点击进入
    在这里插入图片描述

格式化JS代码 & 打XHR断点

  1. 点击进入js代码后,点击代码片段左下角的花括号,格式化js代码,同时根据上面的分析,搜索JSON.parse方法
    在这里插入图片描述
  2. 可以看到搜索结果有11个,但此处我们应该找入参由他自定义解析出的数据,不要选成了由内置的函数解析的数据,如:l = JSON.stringfy(n),这种就该放过,不打断点。
    在这里插入图片描述
  3. y由前端自定义的方法而来,我们应该在此处打断点,因为这里很可能是解码的js部分。
    在这里插入图片描述

继续寻找,直到整个js文件搜索完成。最后我们在第30行、第38行为其打上断点。
在这里插入图片描述

刷新页面 & 移除无用断点

断点我们已经打好了,下面就需要我们刷新页面或者下滑,继续请求数据,以触发XHR断点。

  1. 刷新页面,触发断点
    在这里插入图片描述
  2. 我们发现断点走在了第30行的位置,这样我们就可以把其他断点去掉
    在这里插入图片描述

控制台 & 逆向分析JS

  1. 点击下一步,让程序往下执行一步,然后观察返回的数据是否是我们所需要的明文数据:
    在这里插入图片描述
  2. 来到控制台打印m的值,观察是否是我们需要的数据
    在这里插入图片描述
  3. 上面m发现是我们的个人信息,并非是我们所需要的数据,因此可直接跳过当前断点
    在这里插入图片描述
  4. 点击resume跳过断点后,发现程序再次走到JS代码的第30行。此时我们单步往下走一行,让程序计算出m的值
    在这里插入图片描述
  5. 控制台输入m,回车,观察控制台返回的是否是我们所需的数据
    在这里插入图片描述

可以看到,成功解析出明文数据,表明断点出的这个方法就是前端的JS解密逻辑处。

定位前端代码 & 完善JS

  1. 新建逆向JS代码,并拷贝这段JS代码
var d = Object(u.a)(s), y = Object(u.b)(d), m = JSON.parse(y);

在这里插入图片描述

  1. 控制台输入对应函数名,获取对应函数详细信息

可以看到上面的JS代码,我们并不知道Object(u.a)是什么意思,那么我们就放行,单步执行断点,待断点执行到Object(u.a)之后,就可以从控制台获取其具体值
在这里插入图片描述

  1. 控制台获取函数具体值:Object(u.a),点击控制台返回结果,查看函数详情
    在这里插入图片描述
  2. 拷贝函数到我们逆向的JS代码
    在这里插入图片描述
    我们逆向的JS代码就成了:
// 将u.a替换为了d1
var d = Object(d1)(s), y = Object(u.b)(d), m = JSON.parse(y);function d1(e) {var t, n, r, o, i, a, u = "", c = 0;for (e = e.replace(/[^A-Za-z0-9\+\/\=]/g, ""); c < e.length;)t = _keyStr.indexOf(e.charAt(c++)) << 2 | (o = _keyStr.indexOf(e.charAt(c++))) >> 4,n = (15 & o) << 4 | (i = _keyStr.indexOf(e.charAt(c++))) >> 2,r = (3 & i) << 6 | (a = _keyStr.indexOf(e.charAt(c++))),u += String.fromCharCode(t),64 != i && (u += String.fromCharCode(n)),64 != a && (u += String.fromCharCode(r));return u
}

重复此步骤,不断完善我们自己新建的JS代码,直到能正确解析出服务器返回的密文数据。

  • 服务器返回的密文数据获取:
    在这里插入图片描述
  • 拷贝到自己的逆向JS代码,然后执行,观察是否能解析成功
    在这里插入图片描述
  • 执行JS代码,解析成功
    在这里插入图片描述

3 JS+Python爬虫结合实战

curl自动生成Python爬虫

  1. 复制请求为curl

在这里插入图片描述

  1. 将curl转换为Python代码

网站链接:https://spidertools.cn/#/curl2Request
在这里插入图片描述

调用execjs执行我们编写的逆向JS

Python代码和js逆向代码都就绪了,剩下的就是我们通过execjs在Python代码中使用了。

全部python代码

demo01-JS逆向入门.py:

import requests
import json
# 执行命令安装:pip install pyExecJs
import execjsheaders = {"accept": "application/json","accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6","content-type": "application/json","origin": "https://www.xiniudata.com","priority": "u=1, i","referer": "https://www.xiniudata.com/industry/newest?from=data","sec-ch-ua": "\"Chromium\";v=\"128\", \"Not;A=Brand\";v=\"24\", \"Microsoft Edge\";v=\"128\"","sec-ch-ua-mobile": "?0","sec-ch-ua-platform": "\"macOS\"","sec-fetch-dest": "empty","sec-fetch-mode": "cors","sec-fetch-site": "same-origin","user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0"
}
cookies = {"btoken": "ZOH2JO8CQ3CUE1YH9PC3K6TG1Z3HCEAE","hy_data_2020_id": "192383e583c10e1-06189fe412f809-7e433c49-1484784-192383e583d26f6","hy_data_2020_js_sdk": "%7B%22distinct_id%22%3A%22192383e583c10e1-06189fe412f809-7e433c49-1484784-192383e583d26f6%22%2C%22site_id%22%3A211%2C%22user_company%22%3A105%2C%22props%22%3A%7B%7D%2C%22device_id%22%3A%22192383e583c10e1-06189fe412f809-7e433c49-1484784-192383e583d26f6%22%7D","Hm_lvt_42317524c1662a500d12d3784dbea0f8": "1727520463,1727571559","HMACCOUNT": "CA33EC3F1CCD3E5F","utoken": "Z1MNZUNI27IG3HYGMABLAIRRP67D1DF4","username": "Clay","Hm_lpvt_42317524c1662a500d12d3784dbea0f8": "1728100324"
}
url = "https://www.xiniudata.com/api2/service/x_service/person_industry_list/list_industries_by_sort"
data = {"payload": "LBc3V0I6ZGB5bXsxTCQnPRBuDgQVcDhbICcmb2x3AjI=","sig": "45B0ECB73CAE7AEA531F5A39B29023A0","v": 1
}
data = json.dumps(data, separators=(',', ':'))
response = requests.post(url, headers=headers, cookies=cookies, data=data)# 解析json响应,获取加密后数据
# print(response.json()["d"])# 调用我们编写好的逆向JS函数,解密数据
decode_data = execjs.compile(open('./demo01.js', 'r', encoding='utf-8').read()).call('decode_data', response.json()["d"])
print(decode_data)

如果出现报错:execjs not found,执行下面命令安装:

pip install pyExecJs
全部逆向js代码

js解密代码,我们无需理解,直接拷贝即可

// s = '服务器返回的加密数据'
function decode_data(encode_data) {var d = Object(d1)(encode_data), y = Object(d2)(d), m = JSON.parse(y);rte = mreturn rte
}function d1(e) {var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";var t, n, r, o, i, a, u = "", c = 0;for (e = e.replace(/[^A-Za-z0-9\+\/\=]/g, ""); c < e.length;)t = _keyStr.indexOf(e.charAt(c++)) << 2 | (o = _keyStr.indexOf(e.charAt(c++))) >> 4,n = (15 & o) << 4 | (i = _keyStr.indexOf(e.charAt(c++))) >> 2,r = (3 & i) << 6 | (a = _keyStr.indexOf(e.charAt(c++))),u += String.fromCharCode(t),64 != i && (u += String.fromCharCode(n)),64 != a && (u += String.fromCharCode(r));return u
}function d2(e) {_p = "W5D80NFZHAYB8EUI2T649RT2MNRMVE2O";for (var t = "", n = 0; n < e.length; n++) {var r = _p.charCodeAt(n % _p.length);t += String.fromCharCode(e.charCodeAt(n) ^ r)}return t = _u_d(t)
}function _u_d(e) {for (var t = "", n = 0, r = 0, o = 0, i = 0; n < e.length;)(r = e.charCodeAt(n)) < 128 ? (t += String.fromCharCode(r),n++) : r > 191 && r < 224 ? (o = e.charCodeAt(n + 1),t += String.fromCharCode((31 & r) << 6 | 63 & o),n += 2) : (o = e.charCodeAt(n + 1),i = e.charCodeAt(n + 2),t += String.fromCharCode((15 & r) << 12 | (63 & o) << 6 | 63 & i),n += 3);return t
}

验证

执行Python爬虫代码,完整能否正确抓取并解析数据

在这里插入图片描述

完整代码

Github:https://github.com/ziyifast/ziyifast-code_instruction/tree/main/python-demo/spider-demo/spider-js

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

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

相关文章

28 Vue3之搭建公司级项目规范

可以看到保存的时候ref这行被提到了最前面的一行 要求内置库放在组件的前面称为auto fix&#xff0c;数组new arry改成了字面量&#xff0c;这就是我们配置的规范 js规范使用的是airbnb规范模块使用的是antfu 组合prettier&eslint airbnb规范&#xff1a; https://github…

重磅来袭!CMSIS-DAP 脱机烧录器 EasyFlasher 发布~

重磅来袭&#xff01;CMSIS-DAP 脱机烧录器 EasyFlasher 发布~ 目录 重磅来袭&#xff01;CMSIS-DAP 脱机烧录器 EasyFlasher 发布~相关文章1、前言1、产品特点2、功能说明3、支持芯片4、关于烧录5、写在最后 某宝店铺&#xff1a;觉皇工作室 购买链接&#xff1a;https://item…

缓存数据减轻服务器压力

问题:不是所有的数据都需要请求后端的 不是所有的数据都需要请求后端的,有些数据是重复的、可以复用的解决方案:缓存 实现思路:每一个分类为一个key,一个可以下面可以有很多菜品 前端是按照分类查询的,所以我们需要通过分类来缓存缓存代码 /*** 根据分类id查询菜品** @pa…

Linux中的进程间通信之共享内存

共享内存 共享内存示意图 共享内存数据结构 struct shmid_ds {struct ipc_perm shm_perm; /* operation perms */int shm_segsz; /* size of segment (bytes) */__kernel_time_t shm_atime; /* last attach time */__kernel_time_t shm_dtime; /* last detach time */__kerne…

[Linux] Linux 初识进程地址空间 (进程地址空间第一弹)

标题&#xff1a;[Linux] Linux初识进程地址空间 个人主页水墨不写bug &#xff08;图片来源于AI&#xff09; 目录 一、什么是进程地址空间 二、为什么父子进程相同地址的变量的值不同 三、初识虚拟地址、页表 一、什么是进程地址空间 其实&#xff0c;在很久之前&#xf…

【S32K3 RTD MCAL 篇1】 K344 KEY 控制 EMIOS PWM

【S32K3 RTD MCAL 篇1】 K344 KEY 控制 EMIOS PWM 一&#xff0c;文档简介二&#xff0c; 功能实现2.1 软硬件平台2.2 软件控制流程2.3 资源分配概览2.4 EB 配置2.4.1 Dio module2.4.2 Icu module2.4.4 Mcu module2.4.5 Platform module2.4.6 Port module2.4.7 Pwm module 2.5 …

STM32+ADC+扫描模式

1 ADC简介 1 ADC(模拟到数字量的桥梁) 2 DAC(数字量到模拟的桥梁)&#xff0c;例如&#xff1a;PWM&#xff08;只有完全导通和断开的状态&#xff0c;无功率损耗的状态&#xff09; DAC主要用于波形生成&#xff08;信号发生器和音频解码器&#xff09; 3 模拟看门狗自动监…

Oracle架构之数据库备份和RAC介绍

文章目录 1 数据库备份1.1 数据库备份分类1.1.1 逻辑备份与物理备份1.1.2 完全备份/差异备份/增量备份 1.2 Oracle 逻辑备份1.2.1 EXP/IMP1.2.1.1 EXP导出1.2.1.2 EXP关键字说明1.2.1.3 导入1.2.1.4 IMP关键字说明 1.2.2 EXPDP/IMPDP1.2.2.1 数据泵介绍1.2.2.2 数据泵的使用 1.…

通过 Groovy 实现业务逻辑的动态变更

Groovy 1、需求的提出2、为什么是Groovy3、设计参考1_引入Maven依赖2_GroovyEngineUtils工具类3_GroovyScriptVar类4_脚本规则表设计5_对应的实体类6_数据库访问层7_GroovyExecService通用接口 4、测试5、其他的注意事项6、总结 1、需求的提出 在我们日常的开发过程中&#xf…

嵌入式知识点复习(一)

国庆倒数第二天&#xff0c;进行嵌入式课堂测试的复习&#xff1a; 第一章 绪论 1.1 嵌入式系统的概念 嵌入式系统定义 嵌入式系统定位 嵌入式系统形式 嵌入式系统三要素 嵌入式系统与桌面通用系统的区别 1.2 嵌入式系统的发展历程 微处理器的演进历史 单片机的演进历史 …

【易社保-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

【Python】数据可视化之聚类图

目录 clustermap 主要参数 参考实现 clustermap sns.clustermap是Seaborn库中用于创建聚类热图的函数&#xff0c;该函数能够将数据集中的样本按照相似性进行聚类&#xff0c;并将聚类结果以矩阵的形式展示出来。 sns.clustermap主要用于绘制聚类热图&#xff0c;该热图通…

用manim实现Gram-Schmidt正交化过程

在线性代数中&#xff0c;正交基有许多美丽的性质。例如&#xff0c;由正交列向量组成的矩阵(又称正交矩阵)可以通过矩阵的转置很容易地进行反转。此外&#xff0c;例如&#xff1a;在由彼此正交的向量张成的子空间上投影向量也更容易。Gram-Schmidt过程是一个重要的算法&#…

Python Tips6 基于数据库和钉钉机器人的通知

说明 起因是我第一版quant程序的短信通知失效了。最初认为短信是比较即时且比较醒目的通知方式&#xff0c;现在看来完全不行。 列举三个主要问题&#xff1a; 1 延时。在早先还能收到消息的时候&#xff0c;迟滞就很严重&#xff0c;几分钟都算短的。2 完全丢失。我手机没有…

AI 时代:产品经理不“AI”就出局?

即便你没想去做“AI 产品经理”&#xff0c;那你也不能成为一个不会用 AI 的产品经理。 产品经理肯定是所有互联网从业者中&#xff0c;最先捕捉到 AI 趋势的岗位。 但只知道 AI、关注 AI 还不够&#xff0c;仔细审视一下&#xff1a;你自己的工作&#xff0c;被 AI 提效了么…

《Windows PE》4.1导入表

导入表顾名思义&#xff0c;就是记录外部导入函数信息的表。这些信息包括外部导入函数的序号、名称、地址和所属的DLL动态链接库的名称。Windows程序中使用的所有API接口函数都是从系统DLL中调用的。当然也可能是自定义的DLL动态链接库。对于调用方&#xff0c;我们称之为导入函…

安防监控/视频系统EasyCVR视频汇聚平台如何过滤134段的告警通道?

视频汇聚/集中存储EasyCVR安防监控视频系统采用先进的网络传输技术&#xff0c;支持高清视频的接入和传输&#xff0c;能够满足大规模、高并发的远程监控需求。平台支持国标GB/T 28181协议、部标JT808、GA/T 1400协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为…

STM32定时器(TIM)

目录 一、概述 二、定时器的类型 三、时序 四、定时器中断基本结构 五、定时器定时中断代码 六、定时器外部时钟代码 一、概述 TIM(Timer)定时器 定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断16位计数器、预分频器、自动重装寄存器的时基…

力扣刷题 | 两数之和

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 给定一个整数数组 nums 和…