Js逆向分析+Python爬虫结合

news2024/10/5 19:38:13

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 execjs


headers = {
    "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 = m
    return 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.coloradmin.cn/o/2190418.html

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

相关文章

自闭症干预寄宿学校:为孩子搭建沟通与社交的桥梁

在探索自闭症儿童教育的广阔天地里&#xff0c;一所优秀的寄宿学校不仅是知识的殿堂&#xff0c;更是孩子们学习沟通与社交技能的桥梁。位于广州的星贝育园自闭症儿童寄宿制学校&#xff0c;正是这样一所专注于为自闭症儿童提供全面、个性化教育服务的机构&#xff0c;它以其独…

Linux-du命令使用方法

Linux-du&#xff08;disk useage&#xff09;命令 du 命令用于查看文件和目录占用的磁盘空间。 du [选项] [文件或目录]-h (human-readable)&#xff1a; 将输出格式转为人类可读的形式&#xff0c;使用 KB、MB 等单位。 du -h /path/to/directory1.5M /path/to/directory…

Pikachu-SSRF(curl / file_get_content)

SSRF SSRF是Server-side Request Forge的缩写&#xff0c;中文翻译为服务端请求伪造。产生的原因是由于服务端提供了从其他服务器应用获取数据的功能且没有对地址和协议等做过滤和限制。常见的一个场景就是&#xff0c;通过用户输入的URL来获取图片。这个功能如果被恶意使用&am…

Linux 之 安装软件、GCC编译器、Linux 操作系统基础

安装软件、GCC编译器、Linux 操作系统基础 学习任务&#xff1a; 安装 Vmware虚拟机、掌握Ubuntu 系统的使用认识 Ubuntu 操作系统的终端和 Shell掌握软件安装、文件系统、掌握磁盘管理与解压缩掌握 VIM 编辑器、Makefile 基本语法熟悉 Linux 常见指令操作 安装好开发软件&…

力扣189.轮转数组

给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 3 步: [5,6,7,1,2,3,4…

数据库(MySQL):使用命令从零开始在Navicat创建一个数据库及其数据表(一).创建基础表

一. 使用工具和命令 1.1 使用的工具 Navicat Premium 17 &#xff1a;“Navicat”是一套可创建多个连接的数据库管理工具。 MySQL版本8.0.39 。 1.2 使用的命令 Navicat中使用的命令 命令命令解释SHOW DATABASES&#xff1b;展示所有的数据库CREATE DATABASE 数据库名称; 创…

10以内数的分解

// 10以内数的分解.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 //#include <iostream> using namespace std; int main(int argc, char* argv[]){for (int i 2; i < 10; i){for (int j 1; j < i; j){printf("%d%d%d ",j…

CSS样式基础样式选择器(案例+代码实现+效果图)

目录 1.css样式的规则 2.引入css样式的方式 1)行内式 2)内嵌式 3)外链式 1-link导入 2-import导入 4)总 3.css基础选择器 1)标签选择器 案例&#xff1a;使用标签选择器编写一个圆 1.代码 2.效果 2)类选择器 案例&#xff1a;使用类选择器为div添加背景色 1.代码 2.效果 3)id…

深度探索Kali Linux的精髓与实践应用

Kali Linux简介 Kali Linux作为全球网络安全领域的首选操作系统之一&#xff0c;其强大的功能性及广泛的适用范围令人瞩目。除了上述基础介绍外&#xff0c;让我们深入探究Kali Linux的几个关键特性及其在实际操作中的具体应用案例。 Kali工具集成&#xff1a;全面的安全工具…

加湿器模块(5V STM32)

目录 一、介绍 二、模块原理 1.原理图 2.引脚描述 3.尺寸介绍 三、程序设计 main.c文件 jsq.h文件 jsq.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 加湿器模块通常是指在智能家居设备中负责增加室内空气湿度的部分&#xff0c;这种模块设计旨在改善干燥环…

osg 矩阵相关

下面结果是一样的 osg::Matrix mtrixx;mtrixx.makeRotate(90 / 180.f * osg::PI, osg::Vec3(1, 0, 0));osg::Matrix mtrixx12 osg::Matrix::rotate(90 / 180.f * osg::PI, 1, 0, 0); 备注&#xff1a; rotate或makerotate第一个参数是弧度&#xff0c;可以用 弧度值osg::in…

Pre-trained Natural Language Understanding for Task-Oriented Dialogue

前言 众所周知,预训练BERT语言模型在许多NLP任务重大放异彩,用来文本内容和语义的表征学习很有效果,而且大大降低了下游任务的训练时间。但是由于普通文本和任务型对话之间的语言模式的潜在差异,使得现在的预训练语言模型在实际使用中作用不大。 至于对话领域的预训练语言…

MS-900认证:Microsoft 365 Certified: Fundamentals

一、什么是MS-900认证&#xff1f; MS900认证&#xff0c;全称是 Microsoft 365 Fundamentals&#xff0c;是微软提供的一项认证考试&#xff0c;它旨在验证考生对 Microsoft 365 服务和功能的理解&#xff0c;包括云服务概念、核心服务、安全性、合规性、隐私以及支持和定价信…

【CTF Web】Pikachu CSRF(get) Writeup(CSRF+GET请求+社会工程学)

CSRF(跨站请求伪造)概述 Cross-site request forgery 简称为“CSRF”&#xff0c;在CSRF的攻击场景中攻击者会伪造一个请求&#xff08;这个请求一般是一个链接&#xff09;&#xff0c;然后欺骗目标用户进行点击&#xff0c;用户一旦点击了这个请求&#xff0c;整个攻击就完成…

IDEA的lombok插件不生效了?!!

记录一下&#xff0c;防止找不到解决方案&#xff0c;已经遇到好几次了 前面啰嗦的多&#xff0c;可以直接跳到末尾的解决方法&#xff0c;点击一下 问题现场情况 排查过程 确认引入的依赖正常 —》&#x1f197; idea 是否安装了lombok插件 --》&#x1f197; 貌似没有问题…

锐键网络文档链接

锐键网络文档 锐键网络官网锐捷网络官网首页锐捷网络-场景创新&#xff0c;驱动数字未来锐键网络锐键网络产品中心锐键网络产品中心https://www.ruijie.com.cn/cp/锐键网络交换机【锐捷交换机】以太网交换机_网络交换机-锐捷网络锐键网络无线企业无线产品|无线网络设备-无线AP-…

Redis基础二(spring整合redis)

Springboot整合Redis 一、Springboot整合redis ​ redis可以通过使用java代码来实现 第一部分文档中 在终端操作redis的所有命令&#xff0c;Spring已经帮我们封装了所有的操作&#xff0c;所以变得很简单了。 ​ Spring专门提供了一个模块来进行这些操作的封装&#xff0c;这…

文件路径、文件系统操作、字节流字符流、文件内容操作、自己实现文件查找 删除 复制、IO报错:拒绝访问

目录 一、什么是文件 文件的分类 文件路径 二、文件系统操作 四、文件内容操作 字节流字符流 1&#xff09;字节流&#xff08;二进制文件&#xff09; InputStream概述 FileInputStream 概述 OutputStream 概述 2&#xff09;字符流&#xff08;文本文件&#xf…

资料文档中心

华三文档中心 华三云计算文档中心各个方向(云计算 大数据 路由器 交换机 无线 物联网 安全 光模块 智能管理与运维 移动通信 服务器 存储 PON ICG信息通信 EPCN网关 License Server 其他产品 智能终端 传输产品 云简网络 商用终端 ALGC SMB 产品)云计算-云计算产品-云计算解决…

产品经理-需求分析

需求分析 1.什么是需求&#xff1f; 需求&#xff1a;其本质就是用户的预期&#xff0c;而预期与现状之间存在着差异&#xff0c;就出现了需求另外&#xff0c;用户提出需求时&#xff0c;都会基于某种目的所提出问题、建议或者想法 原始需求的目的是为了避免扯皮&#xff0c;…