声明
本文写于2026年04月13日,仅做技术学习交流。本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
一、前言
网站:https://www.spiderdemo.cn/authentication/jsvmp2_challenge/?challenge_type=jsvmp2_challenge
AI的浪潮里,回归古法自动化(水一篇)
二、抓包
我们按F12,点击网络,可以看到一条数据都抓不到
那么我们打开18080端口直接监听浏览器数据
可以看到发送的是wss的数据,但是请求和回调数据都是加密的
因此我们还得从网页入手,可以看到网页初始化的时候初始化了Worker,
那我们直接RPC调用就行,没啥说的,直接看代码
functioncreateRPC() {
const port = window._root_workerPort_37;
if (!port) {
console.error("❌ Worker port 不存在");
returnnull;
}
let seq = 0;
const pending = newMap();
const _desc = Object.getOwnPropertyDescriptor(MessageEvent.prototype, "data");
if (_desc && _desc.get) {
const rawGet = _desc.get;
Object.defineProperty(MessageEvent.prototype, "data", {
get() {
const r = rawGet.call(this);
try {
if (r?.type === "WS_MESSAGE") {
console.log("收到 WS_MESSAGE:", r);
const task = pending.get("last");
if (task) {
pending.delete("last");
task.resolve(r);
}
}
} catch (e) {}
return r;
}
});
}
functionsendPage(pageNum) {
const req = {
type: "PAGE",
data: {
page: pageNum
}
};
console.log("SEND:", req);
port.postMessage(req);
}
functioncall(pageNum, timeout = 5000) {
returnnewPromise((resolve, reject) => {
const id = ++seq;
pending.set("last", { resolve, reject });
sendPage(pageNum);
setTimeout(() => {
if (pending.has("last")) {
pending.delete("last");
reject("RPC timeout");
}
}, timeout);
});
}
return {
sendPage,
call
};
}
const rpc = createRPC();
functionextractNumbersFromWSMessage(res) {
const data = res?.data;
const numbers = [];
functionwalk(arr) {
if (!Array.isArray(arr)) return;
for (const v of arr) {
if (typeof v === "string" && /^\d+$/.test(v)) {
numbers.push(v);
} elseif (Array.isArray(v)) {
walk(v);
}
}
}
walk(data);
return numbers;
}
rpc.call(55).then(res => {
const nums = extractNumbersFromWSMessage(res);
console.log("page 55:", nums);
});
可以看到直接出值了
本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请在公众号联系作者立即删除!