爬虫工程师也应该了解的 NodeJs 基础(三) - Express 在 Js 逆向中的应用
什么是 Express ?
Express 是一个基于 NodeJS 的 Web Server 开发框架,能够帮助我们快速的搭建 Web 服务器
为什么需要 Express ?
1、不使用框架,使用原生的 NodeJS 开发 Web 服务器,我们需要处理很多繁琐且没有技术含量的内容,例如:获取路由,处理路由等等
2、 不使用框架,使用原生的 NodeJS 开发 Web 服务器,需要解析 get、post 参数解析,使用 Express 可以使用现成的插件实现上面的功能,只要关心核心的业务逻辑即可
3、在 js 逆向中,使用的 execjs 经常会出现一些未知的 bug,导致我们调用出现错误,如果使用 express 运行本地 web 接口可以大大的减少工作量,完成加密算法的调度
如何使用 Express ?
不会的建议回顾一下上一篇文章
juejin.cn/post/703265…
手动安装
npm install express 复制代码
简单使用
const express = require("express") const app = express() app.get('/',function(req,res){ res.send('hello,express') }) app.listen(3000,()=>{ console.log("监听端口3000成功") }) 复制代码
返回静态资源
const express = require("express") const path = require("path") const app = express() app.get('/',function(req,res){ res.send('hello,express') }) // 这里的 pathname 是存放静态资源的路径 app.use(express.static(path.join(__dirname,'pathname'))); app.listen(3000,()=>{ console.log("监听端口3000成功") }) 复制代码
获取 get 请求参数
const express = require("express") const app = express() app.get('/',function(req,res){ res.send(req.query) }) app.listen(3000,()=>{ console.log("监听端口3000成功") }) 复制代码
获取 get 请求参数测试结果
获取 post 请求参数
安装
npm install body-parser 复制代码
例子
const express = require("express"); const bodyParser = require('body-parser'); const app = express(); // app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended : false})); app.post('/',function(req,res){ res.send(req.body['name']) }); app.listen(3000,()=>{ console.log("监听端口3000成功") }); 复制代码
获取 post 请求参数截图
Express 在 Js 逆向中的应用
通过上面的两个例子已经可以学会关于 express 是如何处理请求参数的了,现在就把它应用到 Js 逆向中
在之前我们处理 Js 加密使用的是 python
的 execjs
这个包已经很久没有更新了,经常会出现一些未知的bug
,所以我们今天就要放弃execjs
使用express
来处理加密的 js
直接上一段之前文章的测试代码
先是 Python + execjs 版本
Python + execjs 版本:
import requests import execjs # 用 postman 直接生成的,勿喷 url = "https://xd.newrank.cn/xdnphb/nr/cloud/douyin/rank/hotAccountAllRankList" # 这里的 crack_xd.js 就是 js 加密逻辑 with open('crack_xd.js',"r") as f: js_data = f.read() js_data = execjs.compile(js_data) params = js_data.call("get_params","/xdnphb/nr/cloud/douyin/rank/hotAccountAllRankList") print(params) payload = "{\"date\":\"2020-08-16\",\"date_type\":\"days\",\"type\":\"娱乐\",\"start\":1,\"size\":20}" headers = { 'authority': "xd.newrank.cn", 'pragma': "no-cache", 'cache-control': "no-cache,no-cache", 'accept': "application/json, text/plain, */*", 'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36", 'content-type': "application/json;charset=UTF-8", 'origin': "https://xd.newrank.cn", 'sec-fetch-site': "same-origin", 'sec-fetch-mode': "cors", 'sec-fetch-dest': "empty", 'referer': "https://xd.newrank.cn/data/tiktok/rank/overall", 'accept-language': "zh-CN,zh;q=0.9,en;q=0.8", 'cookie': "Hm_lvt_e20c9ff085f402c8cfc53a441378ca86=1597660797; Hm_lpvt_e20c9ff085f402c8cfc53a441378ca86=1597660859; token=62621CBEE73B4CF98CAA79A77958EA9D", 'Postman-Token': "30dbcaa8-0e0e-44f0-b3ad-b6ddf9c90921" } response = requests.request("POST", url, data=payload.encode(), headers=headers, params=params) print(response.text) 复制代码
可以看到我们需要先把加密的代码抠出来,然后再使用 execjs 调用这个加密的方法,这个过程中要处理加密的算法的编码问题,以及调度过程中不同语言的编码转换,还有一些调用的 bug
如果使用 Python + express,就很简单了
Python + express 版本:
import requests import execjs url = "https://xd.newrank.cn/xdnphb/nr/cloud/douyin/rank/hotAccountAllRankList" def get_params(): params_url = "http://localhost:3000" headers = { 'Connection': "keep-alive", 'Accept-Language': "zh-CN,zh;q=0.9,en;q=0.8", 'Content-Type': "application/x-www-form-urlencoded", 'cache-control': "no-cache", } payload = "callback=u_params('/xdnphb/nr/cloud/douyin/rank/hotAccountAllRankList')" response = requests.post(params_url, headers=headers, data=payload) return response.text params = get_params() payload = "{\"date\":\"2020-08-16\",\"date_type\":\"days\",\"type\":\"娱乐\",\"start\":1,\"size\":20}" headers = { 'authority': "xd.newrank.cn", 'pragma': "no-cache", 'cache-control': "no-cache,no-cache", 'accept': "application/json, text/plain, */*", 'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36", 'content-type': "application/json;charset=UTF-8", 'origin': "https://xd.newrank.cn", 'sec-fetch-site': "same-origin", 'sec-fetch-mode': "cors", 'sec-fetch-dest': "empty", 'referer': "https://xd.newrank.cn/data/tiktok/rank/overall", 'accept-language': "zh-CN,zh;q=0.9,en;q=0.8", 'cookie': "token=62621CBEE73B4CF98CAA79A77958EA9D; Hm_lvt_e20c9ff085f402c8cfc53a441378ca86=1597660797,1598777678; Hm_lpvt_e20c9ff085f402c8cfc53a441378ca86=1598777678; _uab_collina=159877767862449280501573", 'Postman-Token': "30dbcaa8-0e0e-44f0-b3ad-b6ddf9c90921" } response = requests.request("POST", url, data=payload.encode(), headers=headers, params=params) print(response.text) 复制代码
express 代码样例:
const express = require("express"); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.urlencoded({extended : false})); /* 中间省略加密的逻辑代码 */ app.post('/',function(req,res){ let params = req.body['callback']; console.log(params) let value = eval(params); res.send(value) }); app.listen(3000,()=>{ console.log("监听端口3000成功") }); 复制代码
直接使用 python 访问已经搭建好的接口就行了
代码运行结果
以上就是这次的全部内容了,咱们下次再会 ~
作者:咸鱼学Python
链接:https://juejin.cn/post/7032890658671034381