這裏headers頭部有個參數需要分析,然後去搜索定位:
a.default來自t函數,t又是r的構造函數,複製這個r,把new a.default改成 new r到本地
完整逆向代碼:
// 导入 Node.js 内置的 crypto 模块
const crypto = require('crypto');
/**
* 使用 MD5 对字符串进行哈希加密,返回十六进制字符串。
* @param {string} inputString - 要加密的字符串。
* @returns {string} MD5 哈希的十六进制表示。
*/
function md5Encrypt(inputString) {
// 1. 创建一个 MD5 哈希对象
const hash = crypto.createHash('md5');
// 2. 更新哈希对象的数据
// inputString 必须是字符串或 Buffer。如果 inputString 是字符串,默认使用 UTF-8 编码。
hash.update(inputString);
// 3. 计算哈希值并以十六进制格式输出
return hash.digest('hex');
}
r = function () {
function t(t) {
this.clientKey = "B3AA12B0145E1982F282BEDD8A3305B89A9811280C0B8CC3A6A60D81022E4903",
this.saleSubjectCode = "Wanda",
this.cCode = "1_3",
this.mxAPIVer = "v1.0.0",
this.method = "GET",
this.appId = "3"
}
return t.prototype.generateSignature = function (t, e, i) {
var n = "";
return n += this.saleSubjectCode,
n += this.cCode,
n += this.clientKey,
n += t,
"POST" === this.method ? (n += e,
n += i) : (n += e,
i && (n += "?",
n += i)),
md5Encrypt(n)
}
,
t.prototype.setPostData = function (t) {
var e = [];
for (var i in t)
"POST" === this.method ? "object" == typeof t[i] ? e.push(this.flatParamObjectValue(i, t[i])) : e.push(i + "=" + this.urlEncodeUnicode(t[i])) : e.push(i + "=" + encodeURIComponent(t[i]));
return e.join("&")
}
,
t.prototype.setMxHead = function (t, e, i) {
var n = {
ver: "v1.0.0",
sCode: this.saleSubjectCode,
_mi_: t,
width: 1280,
json: !0,
cCode: this.cCode,
check: i,
ts: e,
heigth: 720,
appId: this.appId
};
return JSON.stringify(n)
}
,
t.prototype.flatParamObjectValue = function (t, e) {
var i = [];
for (var n in e)
"object" == typeof e[n] ? i.push(this.flatParamObjectValue(t + "[" + n + "]", e[n])) : i.push(t + "[" + n + "]=" + this.urlEncodeUnicode(e[n]));
return i.join("&")
}
,
t.prototype.urlEncodeUnicode = function (t) {
"string" != typeof t && (t += "");
for (var e = t.length, i = [], n = 0; n < e; n++) {
var o = t.charAt(n)
, a = t.charCodeAt(n);
a > 0 && a < 255 ? this.isSafe(o) ? i.push(o) : " " === o ? i.push("+") : (i.push("%"),
i.push(this.intToHex(a >> 4 & 15)),
i.push(this.intToHex(15 & a))) : (i.push("%u"),
i.push(this.intToHex(a >> 12 & 15)),
i.push(this.intToHex(a >> 8 & 15)),
i.push(this.intToHex(a >> 4 & 15)),
i.push(this.intToHex(15 & a)))
}
return i.join("")
}
,
t.prototype.intToHex = function (t) {
return t <= 9 ? String.fromCharCode(t + 48) : String.fromCharCode(t - 10 + 97)
}
,
t.prototype.isSafe = function (t) {
if (t >= "a" && t <= "z" || t >= "A" && t <= "Z" || t >= "0" && t <= "9")
return !0;
switch (t) {
case "'":
case "(":
case ")":
case "*":
case "-":
case ".":
case "_":
case "!":
return !0
}
return !1
}
,
t
}()
function Get_MX_API(timestamp) {
t = {
"baseUrl": "api/proxy/content",
"path": "/pc/command/commendDatas.api",
"method": "get",
"data": {
"pageSymbol": "pc_index",
"areaSymbol": "pc_index_1",
"json": "true",
"tt": timestamp
}
}
var i, c = new r(t.method), A = (new Date).getTime(), p = c.setPostData(t.data), d = c.generateSignature(A, t.path, p), u = "";
i = c.setMxHead(u, A, d)
return i
}
然後是Python調用:
import time
import requests
import execjs
def runJS(filePath, funcName, *args):
with open(filePath, 'r', encoding='utf-8') as f:
jscode = f.read()
ctx = execjs.compile(jscode)
res = ctx.call(funcName, *args)
return res
t = int(time.time() * 1000)
MX_API = runJS('万达影院在线.js', 'Get_MX_API', t)
headers = {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'zh-TW,zh;q=0.9',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'MX-API': MX_API,
'Pragma': 'no-cache',
'Referer': 'https://www.wandacinemas.com/',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest',
'sec-ch-ua': '"Chromium";v="136", "Google Chrome";v="136", "Not.A/Brand";v="99"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
}
params = {
'tt': t,
}
response = requests.get(
'https://www.wandacinemas.com/api/proxy/content/pc/movie/coming.api',
params=params,
headers=headers,
)
print(response.text)