逆向爬虫29 替换execjs的两种方法
一. 问题引入
最近做js逆向扣取完网站的加密逻辑js代码放到本地用python的 execjs
模块运行的时候, 总会遇这样一个问题。
在浏览器中可以运行, 在js调试工具中可以运行, 甚至在nodejs中也可以运行, 但在python的 execjs
模块中就会报 gbk
编码错误。
多次使用修改编码方式解决无果后, 就和群里大佬们请教, 得知了两个解决方案。
- 使用python的
subprocess模块
, 在命令行中自己调用node xxx.js的方式来运行。 - 使用nodejs的
express Web框架
, 搭建一个http API接口
, 使用python的requests模块
对该接口进行访问, 获取起返回结果。
下面就来介绍这两种解决方案的具体实现过程。
二. 使用subprocess调用nodejs执行js文件
js代码如下
// 前面省略了从网页中扣出来的代码
function encryptPwd() {
var arguments = process.argv.splice(2); // 获取命令行参数
var enc = new JSEncrypt();
enc.setPublicKey("-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAbfx4VggVVpcfCjzQ+nEiJ2DLnRg3e2QdDf/m/qMvtqXi4xhwvbpHfaX46CzQznU8l9NJtF28pTSZSKnE/791MJfVnucVcJcxRAEcpPprb8X3hfdxKEEYjOPAuVseewmO5cM+x7zi9FWbZ89uOp5sxjMnlVjDaIczKTRx+7vn2wIDAQAB-----END PUBLIC KEY-----");
console.log(enc.encrypt(arguments[0]));
}
encryptPwd();
python代码如下
import subprocess
password = '123456'
result = subprocess.check_output(f"node encrypt.js {password}", shell=True)
print(result.decode('utf-8').strip())
上述代码相当与在命令行中执行 node encrypt.js 123456
命令
参考链接
三. 调用express web API接口
js包含两个文件:1. encrypt.js (抠出来的加密逻辑js) 2. main.js (express启动文件)
// encrypt.js
// 前面省略了从网页中扣出来的代码
function encryptPwd(password) {
var enc = new JSEncrypt();
enc.setPublicKey("-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAbfx4VggVVpcfCjzQ+nEiJ2DLnRg3e2QdDf/m/qMvtqXi4xhwvbpHfaX46CzQznU8l9NJtF28pTSZSKnE/791MJfVnucVcJcxRAEcpPprb8X3hfdxKEEYjOPAuVseewmO5cM+x7zi9FWbZ89uOp5sxjMnlVjDaIczKTRx+7vn2wIDAQAB-----END PUBLIC KEY-----");
return enc.encrypt(password);
}
// 导出该函数
module.exports = {
encryptPwd
}
要使用express请先确认电脑上是否有nodejs, 装好后还需要在当前目录执行 npm i express
安装express
// main.js
// 引入依赖包
var express = require('express');
var bodyParser = require('body-parser');
// 引入自定义的JS文件
var enc = require('./encrypt.js');
// 创建应用实例
var app = express();
// 判断请求体格式是不是表单格式,如果是的话会调用qs库把请求体字符串转成对象
app.use(bodyParser.urlencoded({extended: true}));
// 判断请求体格式是不是json格式,如果是的话会调用JSON.parse方法把请求体字符串转成对象
app.use(bodyParser.json())
// 上面两个只有一个会生效
// 创建路由
// app.post(path, function(req, res) {具体逻辑})
app.post('/encrypt', function(req, res) {
let result = req.body;
console.log('result', result);
result = enc.encryptPwd(result.password);
res.send(result);
})
// 启动服务,监听指定主机和端口上的连接
app.listen(3000, () => {
console.log('开启服务,端口3000')
})
参考链接:直接从视频的 1:15:00 左右开始看就可以了