如何用node.js执行js代码
在爬虫的js逆向项目中,常常会直接在网页的源码中抠出js混淆代码,一般会用pyexecjs库调用执行js代码得到加密参数。但是这个库据作者所说可能会停止更新了,而且pyexecjs执行js代码的效率是很低下的,远不如浏览器的效率。如果在大规模高并发的爬虫的项目中,使用pyexecjs会大大的限制爬虫的性能。
因此,本文将介绍用node.js来执行js代码,node.js执行js的效率非常的高,如果把node.js部署在服务器上,直接用接口访问服务器执行js代码返回加密参数是一个很好的选择。本文将介绍pyexecjs和node.js两种方法,关于node.js和pyexecjs的安装方法不再叙述,网上一搜一大堆。
1.pyexecjs的使用
先创键一个js文件命名为sum.js,该文件只简单的写一个js方法,如下所示:
function add(a, b) {
return a + b;
}
然后再创建一个test_execjs.py文件用pyexecjs库调用上面的js代码得到返回结果,如下所示:
import time
import execjs
with open('sum.js', 'r') as file:
js_code = file.read()
start_time = time.time()
execjs_handle = execjs.compile(js_code)
result = execjs_handle.call('add', 5, 7)
total_time = time.time() - start_time
print('result:', result)
print('cost_time:', total_time)
暂不解释代码的意思,先看看这感人的执行效率
result: 12
cost_time: 0.1277756690979004
怎么样,就仅仅是执行一个最简单的加法的方法就用时0.127秒,试想这效率怎么可能满足大规模爬虫的应用。
再来解释一下上面代码的意思,首先是导入库,然后把js代码从sum.js文件里面读取出来,再把代码传到execjs的compile方法得到一个句柄,最后通过方法名调用方法,传入参数即可得到add方法返回的运算结果。至于关于时间的代码都是为了计算execjs执行js代码耗费的时间的。当然execjs库还有其他的方法可供使用,但是不常用,反正我是从来没用到过,可以自行查看。
2.node.js调用js代码
首先说一下这里不细致的介绍node.js,node.js是一个非常强大的工具,对于使用node.js调用js代码只需要搞懂我下面所说的就行了。
首先还是创建一个sum.js文件,文件内容如下:
function add(a, b) {
return a + b;
}
module.exports = {
add
}
只是比上面创建的sum.js多了几行,一定要写module.exports,把方法名放进大括号里面,只要这样才能在外部调用这个方法,切记只需要写方法名就行别传参,切记!按照我上面写的改就行了。
然后是实现一个node.js的服务器程序,创建一个js文件main.js,内容如下所示:
var express = require('express');
var bodyParser = require('body-parser');
var sum = require('./sum');
var app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
// post请求方式
// app.post('/get_num', function (req, res) {
// let result = req.body;
// let a = parseInt(result.a);
// let b = parseInt(result.b);
// result = sum.add(a,b);
// res.send(result.toString());
// });
// get请求方式
app.get('/get_num', function (req, res) {
let a = parseInt(req.query.a);
let b = parseInt(req.query.b);
result = sum.add(a, b);
res.send(result.toString());
});
app.listen(3000, () => {
console.log('开启服务,端口3000')
});
这里面我实现了两种请求方式post和get,随便选择一种就行,只需要看懂post和get请求方法的内容就行,在请求方法中接收请求的参数,然后调用add方法,最后把add返回的结果再返回给客户端就齐活。执行上面的代码就会在本地的3000端口开一个服务器用来监听请求,一定把这个代码跑起来,后面要用!
接下来创建一个test_nodejs.py文件来请求node.js,如下所示:
import time
import requests
url = "http://localhost:3000/get_num"
data = {
'a': 5,
'b': 9
}
start_time = time.time()
# response = requests.post(url, data=data)
response = requests.get(url, params=data)
total_time = time.time() - start_time
print(response.text)
print('cost_time:', total_time)
先来看看执行的结果
result: 14
cost_time: 0.020343303680419922
看出来差距没,用node.js执行同样的代码只需要0.02秒,执行效率是pyexecjs的6倍还多,快不快?
上面的代码想必也不用我再解释啥意思了吧,有python基础的应该都能看懂,注意一下我也实现了一个post请求,请根据node.js服务器实现的请求方式来决定这个是用post还是get去请求。
好啦,介绍完了,如果是js逆向的代码只需要把你的代码替换掉上面sum.js文件中的add方法就可以了,别忘了module.exports中的方法名也要相应的改掉。
以后把node.js部署到服务器上比如阿里云或者腾讯云上面不就可以很方便的得到js加密参数啦。
欢迎关注我的微信公众号:丸子打豆豆