python爬虫js逆向入门

js基础

在 JavaScript 逆向工程中,常常会遇到一些复杂的代码结构,这些代码可能包含各种函数定义、对象操作、异步调用等。

### 1. 函数声明和调用function generateSignature(uri, params) {
// 将 uri 和参数对象转换为字符串
var data = uri + '?' + Object.keys(params).map(key => `${key}=${params[key]}`).join('&');
// 使用 SHA256 算法生成签名
return CryptoJS.SHA256(data).toString();
}
// 调用生成签名的函数
var signature = generateSignature("/api/pc/info", { param1: "value1", param2: "value2" });### 2. 异步操作(Promise 和 async/await)// 使用 Promise 进行异步操作
function fetchData(url) {
return new Promise((resolve, reject) => {
// 发起网络请求
fetch(url)
.then(response => response.json()) // 将响应解析为 JSON
.then(data => resolve(data)) // 解析成功,调用 resolve
.catch(error => reject(error)); // 解析失败,调用 reject
});
}// 使用 async/await 进行异步操作
async function getData() {
try {
// 等待 fetchData 函数完成并返回结果
const data = await fetchData('https://api.example.com/data');
console.log(data);
} catch (error) {
console.error('Error:', error);
}
}
getData();### 3. 对象和数组操作// 定义一个对象
let user = {
name: "John",
age: 30,
getDetails: function() {
return `${this.name} is ${this.age} years old.`;
}
};// 调用对象的方法
console.log(user.getDetails()); // 输出: John is 30 years old
// 定义一个数组
let numbers = [1, 2, 3, 4, 5];
// 使用数组方法
numbers.push(6); // 添加元素到数组末尾
console.log(numbers); // 输出: [1, 2, 3, 4, 5, 6]### 4. 常见的算法实现(如加密、哈希)// 使用 CryptoJS 库进行 SHA256 哈希
function hashData(data) {
return CryptoJS.SHA256(data).toString();
}
let hashedValue = hashData("example data");
console.log(hashedValue); // 输出哈希值### 5. 条件判断和三元运算符// 使用 if...else 进行条件判断
function checkNumber(num) {
if (num > 0) {
return "Positive";
} else if (num < 0) {
return "Negative";
} else {
return "Zero";
}
}// 使用三元运算符进行条件判断
function checkNumberTernary(num) {
return num > 0 ? "Positive" : num < 0 ? "Negative" : "Zero";
}
console.log(checkNumber(5)); // 输出: Positive
console.log(checkNumberTernary(-3)); // 输出: Negative### 6. 模块和导入
// 导出一个模块
export function add(x, y) {
return x + y;
}// 导入一个模块
import { add } from './math.js';
console.log(add(2, 3)); // 输出: 5

### 综合示例

// 定义一个生成签名的函数
function generateSignature(uri, params) {
// 将参数对象转换为查询字符串
var data = uri + '?' + Object.keys(params).map(key => `${key}=${params[key]}`).join('&');
// 使用 SHA256 算法生成签名
return CryptoJS.SHA256(data).toString();
}// 异步函数,获取数据并生成签名
async function fetchDataAndSign() {
try {
// 定义请求的 URL 和参数
let url = 'https://api.example.com/data';
let params = { param1: 'value1', param2: 'value2' };// 发起网络请求,获取数据
let response = await fetch(url);
let data = await response.json();// 生成签名
let signature = generateSignature(url, params);
console.log('Signature:', signature);// 返回获取的数据和生成的签名
return { data, signature };
} catch (error) {
// 处理错误
console.error('Error:', error);
}
}// 调用异步函数
fetchDataAndSign();

1. **掌握 JavaScript 基础**:熟悉 JavaScript 的基础知识,包括变量、函数、对象、数组等。

2. **了解异步操作**:理解 JavaScript 中的异步操作,包括 Promise 和 async/await。

3. **使用调试工具**:使用浏览器的开发者工具(如 Chrome DevTools)进行代码调试,设置断点,逐步执行代码,观察变量值。

4. **练习代码阅读**:多阅读和分析实际项目中的 JavaScript 代码,提高代码阅读和理解能力。

简单的 JS 逆向反爬的示例

### 示例场景

在爬取某个网站的数据时,发现请求返回的内容是空的或者无效的。通过检查浏览器开发者工具(F12),发现这个网站在请求中使用了一个名为 `_signature` 的参数,这是一个通过 JavaScript 生成的签名值。

### 步骤 1:发现反爬机制

在浏览器中打开开发者工具,切换到 **Network** 面板,刷新页面,找到相关的请求,注意到请求 URL 中有一个 `_signature` 参数。你发现每次请求的 `_signature` 值都是不同的,这表明这个值是动态生成的。

### 步骤 2:找到相关的 JS 代码

切换到 **Sources** 面板,搜索生成 `_signature` 的代码。通常,可以搜索 `signature` 关键字来找到相关的代码。假设你找到了以下 JavaScript 代码:

function generateSignature(url, params) {
var data = url + '?' + Object.keys(params).map(key => `${key}=${params[key]}`).join('&');
return CryptoJS.SHA256(data).toString();
}// 示例调用var url = "/api/data";
var params = { "param1": "value1", "param2": "value2" };
var signature = generateSignature(url, params);
console.log(signature);

### 步骤 3:分析 JavaScript 代码

从上述代码可以看出,签名是通过 `CryptoJS.SHA256` 方法生成的。需要在 Python 中模拟这个签名生成过程。

### 步骤 4:在 Python 中实现

在 Python 中使用 `hashlib` 库来实现相同的签名生成逻辑:

import hashlib
def generate_signature(url, params):# 将参数转换为查询字符串data = url + '?' + '&'.join([f"{key}={value}" for key, value in params.items()])# 使用 SHA256 生成签名signature = hashlib.sha256(data.encode()).hexdigest()return signature# 示例 URL 和参数
url = "/api/data"
params = { "param1": "value1", "param2": "value2" }
signature = generate_signature(url, params)
print(signature)

### 步骤 5:应用到数据爬取

使用生成的签名值进行实际的数据爬取请求:

import requests
def generate_signature(url, params):data = url + '?' + '&'.join([f"{key}={value}" for key, value in params.items()])signature = hashlib.sha256(data.encode()).hexdigest()return signature# 示例 URL 和参数
url = "/api/data"
params = { "param1": "value1", "param2": "value2" }
# 生成签名
signature = generate_signature(url, params)
# 构造请求 URL
base_url = "https://example.com"
full_url = f"{base_url}{url}?{'&'.join([f'{key}={value}' for key, value in params.items()])}&_signature={signature}"
# 发送请求
response = requests.get(full_url)
# 处理响应
if response.status_code == 200:data = response.json()print(data)
else:print("Request failed:", response.status_code)

### 总结

1. **发现反爬机制**:通过浏览器开发者工具,发现请求中有一个动态生成的 `_signature` 参数。

2. **找到相关的 JS 代码**:在 **Sources** 面板中搜索并找到生成 `_signature` 的 JavaScript 代码。

3. **分析 JS 代码**:理解生成签名的逻辑,通常涉及一些哈希或加密算法。

4. **在 Python 中实现**:使用 Python 实现相同的签名生成逻辑,以便进行合法请求。

5. **应用到数据爬取**:将生成的签名应用到实际请求中,爬取所需的数据。

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

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

相关文章

C++基础入门(上)

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 C基础入门(上) 收录于专栏【C语法基础】 本专栏旨在分享学习C的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 1. C发展历史 2. C版本…

如何在SpringCloud项目中实现断路器模式?

在Spring Cloud项目中实现断路器&#xff08;Circuit Breaker&#xff09;模式可以通过几种不同的库实现&#xff0c;如Netflix Hystrix、Resilience4j或Spring Cloud Circuit Breaker。断路器模式允许您的应用在遇到服务故障时快速失败&#xff0c;防止故障的蔓延和系统过载&a…

ffmpeg 找到编解码器,和编解码器上下文后,是如何初始化具体的编解码器的?aac 初始化流程大致如下

1.当使用 avcodec_find_encoder_by_name找到编码器的时候&#xff0c; const AVCodec * aacencoder avcodec_find_encoder_by_name("libx264"); 编码器 有值的是&#xff1a; id AV_CODEC_ID_H264 (27) long_name libx264 H.264…

read paper and make summer (Image enhancement)

read paper and make summer ==标题==:图像==标题==:低级视觉方法==标题==:颜色直方图==标题==:颜色空间变换==标题==:亮度通道==标题==:色度通道==标题==:图像滤波==标题==:方盒滤波==标题==:均值滤波==标题==:高斯滤波(去噪)==标题==:中值滤波(去噪)==标题==:…

Goland 通道

channel通道 目录 channel通道 channel介绍 channel基本使用 有缓存通道和无缓存通道的区别 通道的初始化&#xff0c;写入数据到通道&#xff0c;从通道读取数据及基本的注意事项 channel的关闭和遍历 channel的关闭 为什么关闭 如何优雅地关闭通道 channel的遍历 chan…

小众好玩的赛车游戏:环道巨星 CIRCUIT SUPERSTARS中文安装包

《环道巨星》&#xff08;Circuit Superstars&#xff09;是一款由赛车迷亲手为其他赛车迷打造的俯视角赛车游戏。荟集史上各类赛车运动&#xff0c;旨在提供刺激好玩的驾驶体验&#xff1b;而游戏自带的高技术难度将促使玩家长时间磨砺技巧&#xff0c;以达成完美的一圈。 游戏…

刷题Day50|739. 每日温度、496.下一个更大元素 I、503.下一个更大元素II

开启单调栈篇章&#xff1a;单调栈用来找任意一个元素左边或者右边第一个比它大/小的元素&#xff08;或位置&#xff09;。 739. 每日温度 739. 每日温度 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;使用一个递增单调栈&#xff0c;可以从头到尾或者从尾到头…

js中scrollIntoView第一次不生效,第二次生效

scrollIntoView 方法用于将元素滚动到可视区域。如果在页面加载后立即使用&#xff0c;可能不会生效&#xff0c;因为页面可能还没有完全渲染或者加载完成。 如果是因为元素还没有完全渲染完成&#xff0c;可以在 requestAnimationFrame 中调用 scrollIntoView。 requestAnima…

C# 建造者模式(Builder Pattern)

建造者模式&#xff08;Builder Pattern&#xff09;&#xff0c;也被称为生成器模式&#xff0c;是一种对象构建模式&#xff0c;旨在将复杂对象的构建过程与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。这种模式特别适用于构建具有多个组成部分的复杂对象&am…

2024前端面试真题【CSS篇】

盒子模型 盒子模型&#xff1a;box-sizing&#xff0c;描述了文档中的元素如何生成矩形盒子&#xff0c;并通过这些盒子的布局来组织和设计网页。包含content、padding、margin、border四个部分。 分类 W3C盒子模型&#xff08;content-box&#xff09;&#xff1a;标准盒子模…

【系统架构设计师】九、软件工程(面向对象方法|逆向工程)

目录 六、面向对象方法 6.1 基本概念 6.2 面向对象的分析 6.2.1 用例关系 6.2.2 类之间的关系 6.3 面向对象的设计 6.4 面向对象设计原则与设计模式 6.5 面向对象软件的测试 七、逆向工程 历年真题练习 六、面向对象方法 面向对象的分析方法 (Object-Oriented Analys…

python输出/sys/class/power_supply/BAT0/电池各项内容

读取 /sys/class/power_supply/BAT0/ 目录下的所有相关文件,并输出其内容: import os# 定义电池信息文件的路径 battery_path = "/sys/class/power_supply/BAT0/"# 读取文件内容的函数 def read_battery_info(file_name):try:with open(os.path.join(battery_path…

Mybatis-Plus中LambdaQueryWrapper

基本用法 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; // 假设有一个 User 实体类 LambdaQueryWrapper<User> queryWrapper new LambdaQueryWrapper<>(); // 添加查询条件 queryWrapper.eq(User::getName, "John&quo…

stm32出现hardfault-自动化分析map文件

可通过如下python脚本进行分析: import os import sys #在此输入HardFault_Handler时打印的PC指针 address 0x20006980 #以下代码不要要更改 def is_hex(data): try: int(data, 16) return True except ValueError: return False def find_line_number(map_file, addre…

Rust编程-I/O

文件读取: 依赖&#xff1a;标准库中use std::fs; 模块 读取文件&#xff1a;fs::read_to_string(filepath:string) -> Result<String> String是文件内容 下面代码来自《Rust权威指南》&#xff0c;主要作用是从文件中检索&#xff0c;并返回检索内容所在的行&#xf…

stm32使用双通道ADC读取

Driver_ADC.c 使用了DMA转换 #include "Driver_ADC.h"void Driver_ADC1_Init(void) {/* 1. 时钟配置 *//* 1.1 adc时钟 */RCC->APB2ENR | RCC_APB2ENR_ADC1EN;RCC->CFGR | RCC_CFGR_ADCPRE_1;RCC->CFGR & ~RCC_CFGR_ADCPRE_0;/* 1.2 gpio的时钟 */RCC…

【Linux网络】数据链路层【上】{初识数据链路层/以太网/路由表/MAC地址表/ARP表/NAT表}

文章目录 1.初识数据链路层2.认识以太网2.0前导知识以太网帧和MAC帧CMSA/CD以太网的最小帧长限制是64字节IP层和MAC层 2.1以太网帧格式 3.预备知识计算机网络通信以太网和wifi路由表/MAC地址表/ARP表/NAT表/ACL表 用于同一种数据链路节点的两个设备之间进行信息传递。 1.初识数…

Apache AGE 聚合函数

简介 一般来说&#xff0c;聚合函数 aggr(expr) 会处理每个聚合键在传入记录中找到的所有匹配行&#xff08;键使用等价性进行比较&#xff09;。 在常规聚合&#xff08;即形式为 aggr(expr) 的情况下&#xff09;&#xff0c;聚合值列表是候选值列表&#xff0c;其中所有空…

系统服务综合案例

系统服务综合案例 具体任务&#xff1a; 现有主机 node01和node02&#xff0c;完成如下需求: 1、在 node01 主机上提供 DNS 和 WEB 服务 2、dns 服务提供本实验所有主机名解析 3、web服务提供www.rhce.com 虚拟主机 4、该虚拟主机的documentroot目录在/nfs/rhce目录 5、该目录…

Clion 使用gdbserver调试FreeSWITCH源码

1.准备环境 window安装clion安装好gdb、ssh、已经编译好的freeswitch可执行文件的docker镜像2.配置clion Settings -> Tools ->SSH Configurations Settings-Build, Execution, Deployment-Toolchains(其实设不设置都行,用默认也行的) Settings-Build, Execution, Depl…