first commit
This commit is contained in:
commit
9399a88d39
347 files changed
+167716
No files matched your search
@@ -0,0 +1,68 @@
|
||||
// 通用:在已登录的闲鱼卖家页上下文里执行一段 JS,结果落盘
|
||||
// 用法: node cdp-eval.mjs <表达式文件> <输出文件>
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
const exprFile = process.argv[2];
|
||||
const outFile = path.resolve(process.argv[3] || '.cdp/out/eval.json');
|
||||
const expr = fs.readFileSync(exprFile, 'utf8');
|
||||
|
||||
const UDD = 'C:\\Users\\Administrator\\AppData\\Local\\Google\\Chrome\\User Data';
|
||||
const lines = fs.readFileSync(path.join(UDD, 'DevToolsActivePort'), 'utf8')
|
||||
.split('\n').map(s => s.trim()).filter(Boolean);
|
||||
|
||||
class Cdp {
|
||||
constructor(ws) { this.ws = ws; this.seq = 0; this.pending = new Map(); }
|
||||
static async attach(url) {
|
||||
const ws = new WebSocket(url);
|
||||
await new Promise((res, rej) => {
|
||||
const t = setTimeout(() => rej(new Error('ws timeout')), 15000);
|
||||
ws.addEventListener('open', () => { clearTimeout(t); res(); }, { once: true });
|
||||
ws.addEventListener('error', () => { clearTimeout(t); rej(new Error('ws error')); }, { once: true });
|
||||
});
|
||||
const c = new Cdp(ws);
|
||||
ws.addEventListener('message', (ev) => {
|
||||
let m; try { m = JSON.parse(ev.data); } catch { return; }
|
||||
if (m.id && c.pending.has(m.id)) {
|
||||
const p = c.pending.get(m.id); c.pending.delete(m.id); clearTimeout(p.timer);
|
||||
m.error ? p.reject(new Error(m.error.message)) : p.resolve(m.result);
|
||||
}
|
||||
});
|
||||
return c;
|
||||
}
|
||||
send(method, params = {}, sessionId, t = 120000) {
|
||||
const id = ++this.seq;
|
||||
return new Promise((res, rej) => {
|
||||
const timer = setTimeout(() => { this.pending.delete(id); rej(new Error('timeout ' + method)); }, t);
|
||||
this.pending.set(id, { resolve: res, reject: rej, timer });
|
||||
const msg = { id, method, params }; if (sessionId) msg.sessionId = sessionId;
|
||||
this.ws.send(JSON.stringify(msg));
|
||||
});
|
||||
}
|
||||
close() { try { this.ws.close(); } catch {} }
|
||||
}
|
||||
|
||||
const cdp = await Cdp.attach(`ws://127.0.0.1:${lines[0]}${lines[1]}`);
|
||||
const { targetInfos } = await cdp.send('Target.getTargets');
|
||||
const page = targetInfos.find(t => t.type === 'page' && /seller\.goofish\.com/.test(t.url));
|
||||
if (!page) { console.log('no seller page'); process.exit(2); }
|
||||
const { sessionId: S } = await cdp.send('Target.attachToTarget', { targetId: page.targetId, flatten: true });
|
||||
console.log('target: ' + page.url);
|
||||
|
||||
const r = await cdp.send('Runtime.evaluate', {
|
||||
expression: expr, returnByValue: true, awaitPromise: true, userGesture: false,
|
||||
}, S, 180000);
|
||||
|
||||
if (r.exceptionDetails) {
|
||||
console.log('EXCEPTION: ' + r.exceptionDetails.text + ' :: ' + (r.exceptionDetails.exception?.description || ''));
|
||||
fs.writeFileSync(outFile, JSON.stringify({ __error: r.exceptionDetails.text, desc: r.exceptionDetails.exception?.description }, null, 2), 'utf8');
|
||||
cdp.close(); process.exit(1);
|
||||
}
|
||||
const v = r.result?.value;
|
||||
fs.mkdirSync(path.dirname(outFile), { recursive: true });
|
||||
fs.writeFileSync(outFile, JSON.stringify(v, null, 2), 'utf8');
|
||||
const head = JSON.stringify(v);
|
||||
console.log('written ' + outFile + ' (' + head.length + ' chars)');
|
||||
console.log(head.slice(0, 1200));
|
||||
cdp.close();
|
||||
process.exit(0);
|
||||
Reference in new issue
Block a user