js基础
在 JavaScript 逆向工程中,常常会遇到一些复杂的代码结构,这些代码可能包含各种函数定义、对象操作、异步调用等。
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
### 综合示例
javascript">// 定义一个生成签名的函数
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 代码:
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` 库来实现相同的签名生成逻辑:
python">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:应用到数据爬取
使用生成的签名值进行实际的数据爬取请求:
python">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. **应用到数据爬取**:将生成的签名应用到实际请求中,爬取所需的数据。