1. 项目背景与目标解析
私募排排网作为国内知名的金融数据平台,其数据展示逻辑采用了前端加密+接口校验的双重防护机制。这给需要批量获取数据的分析师带来了不小挑战。本次逆向工程的目标是突破其数据加密体系,实现自动化采集。
在实际操作中,我发现该网站主要采用以下三种防护手段:
- 动态生成的JS加密函数
- 接口参数签名验证
- 数据内容二次混淆
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 逆向分析核心流程
2.1 加密入口定位技巧
使用Chrome开发者工具的Network面板监控XHR请求时,发现关键数据接口返回的是加密字符串。通过以下特征可以快速定位加密逻辑:
- 响应内容包含明显加密特征(如非常规字符组合)
- 请求参数中存在
sign、token等字段 - 响应头包含自定义加密标识
实战技巧:在Sources面板使用
Ctrl+Shift+F全局搜索encrypt、decode等关键词,能快速定位核心加密函数。
2.2 JS代码调试方法
找到疑似加密函数后,通过以下步骤进行调试:
javascript复制// 在加密函数入口处打调试断点
function encryptData(data) {
debugger; // 手动添加断点
// ...加密逻辑...
}
调试时重点关注:
- 函数调用堆栈(Call Stack)
- 局部变量(Local Scope)变化
- 加密前后的数据对比
2.3 加密算法还原实战
以排排网使用的RSA+AES混合加密为例,还原过程包括:
- 提取公钥模数(modulus)和指数(exponent)
- 逆向密钥生成逻辑
- 模拟前端加密流程
典型的重现代码结构:
python复制def decrypt_response(encrypted_data):
# 步骤1:RSA解密获取AES密钥
aes_key = rsa_decrypt(encrypted_key, private_key)
# 步骤2:AES解密数据
iv = encrypted_data[:16]
cipher = AES.new(aes_key, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(encrypted_data[16:]))
3. 关键问题解决方案
3.1 动态参数处理
对于每次请求变化的_t时间戳参数,需要分析其生成规则。通过Hook Date对象可以发现:
javascript复制// 拦截原始Date对象
const nativeDate = Date;
Date = function() {
// 识别特定格式的时间戳生成逻辑
if (arguments.length === 1 && typeof arguments[0] === 'string') {
return new nativeDate(modifiedTimestamp);
}
return new nativeDate(...arguments);
}
3.2 反调试绕过策略
当网站启用反调试时,可采用以下对策:
- 禁用无限debugger循环:
javascript复制// 重写debugger功能
Function.prototype.constructor = function() {
if (!arguments[0].includes('debugger')) {
return new Function(...arguments);
}
};
- 屏蔽性能监控:
javascript复制// 清空性能标记
window.performance.mark = function(){};
window.performance.measure = function(){};
4. 完整实现方案
4.1 Python实现核心逻辑
python复制import execjs
from Crypto.Cipher import AES
class PaiPaiSpider:
def __init__(self):
self.ctx = execjs.compile(open('decrypt.js').read())
def decrypt_data(self, encrypted):
# 调用JS环境解密
return self.ctx.call('decrypt', encrypted)
def parse_response(self, response):
# 提取加密数据
encrypted = response.json()['data']
# 分步解密
step1 = self.decrypt_stage1(encrypted)
return self.decrypt_stage2(step1)
4.2 补环境技巧
对于检测浏览器环境的JS代码,需要完整模拟:
javascript复制// 补全navigator对象
const fakeNavigator = {
userAgent: 'Mozilla/5.0...',
platform: 'Win32',
hardwareConcurrency: 4,
deviceMemory: 8
};
window.navigator = new Proxy(fakeNavigator, {
get(target, key) {
return target[key] || navigator[key];
}
});
5. 实战注意事项
-
请求频率控制:
- 单IP请求间隔建议≥3秒
- 配合代理池使用,推荐每50次请求更换IP
- 注意监控响应头的
X-RateLimit字段
-
解密失败处理:
python复制def safe_decrypt(data): try: return decrypt_data(data) except Exception as e: logger.error(f"解密失败: {str(e)}") # 重试机制 return self.retry_decrypt(data) -
签名算法更新预警:
- 建议每天首次运行校验测试用例
- 建立签名算法版本管理机制
- 准备降级方案(如人工介入)
6. 性能优化方案
-
JS执行加速:
- 使用PyMiniRacer替代PyExecJS
- 预编译高频调用的JS函数
- 缓存已解析的加密参数
-
内存管理:
python复制# 使用上下文管理器管理JS环境 with JSRuntime() as rt: rt.eval(decrypt_script) result = rt.call('decrypt', data) -
分布式采集架构:
mermaid复制graph TD A[调度中心] --> B[爬虫节点1] A --> C[爬虫节点2] A --> D[爬虫节点3] B --> E[代理池] C --> E D --> E
7. 法律风险规避
- 严格遵守目标网站的robots.txt规定
- 单次采集数据量不超过1000条
- 数据仅用于个人分析研究
- 商业使用需获得官方授权
重要提示:建议在本地解析加密数据,不要直接调用网站接口,避免产生不必要的服务器压力。
8. 扩展应用场景
本方案的技术路线同样适用于:
- 基金净值数据采集
- 上市公司公告解析
- 债券交易数据获取
- 宏观经济指标抓取
通过调整解密逻辑和参数配置,可以快速适配各类金融数据平台的采集需求。在实际项目中,建议先通过少量测试请求验证解密方案的稳定性,再开展大规模采集。
