69 lines
3.3 KiB
JavaScript
69 lines
3.3 KiB
JavaScript
// 浏览器调试能力自检:发现端口 → 连 CDP → 列出标签页 → 读取页面信息
|
||
import fs from 'node:fs';
|
||
import path from 'node:path';
|
||
|
||
const CANDIDATES = [
|
||
'C:\\Users\\Administrator\\AppData\\Local\\Google\\Chrome\\User Data\\DevToolsActivePort',
|
||
'C:\\Users\\Administrator\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\DevToolsActivePort',
|
||
];
|
||
|
||
const log = m => console.log(m);
|
||
let lines = null, usedFile = null;
|
||
for (const f of CANDIDATES) {
|
||
if (fs.existsSync(f)) {
|
||
const raw = fs.readFileSync(f, 'utf8').split('\n').map(s => s.trim()).filter(Boolean);
|
||
if (raw.length >= 2) { lines = raw; usedFile = f; break; }
|
||
}
|
||
}
|
||
if (!lines) { log('NOT_FOUND: 没找到 DevToolsActivePort,说明 Chrome 未以调试模式启动'); process.exit(0); }
|
||
log('端口文件: ' + usedFile);
|
||
log('端口: ' + lines[0] + ' 浏览器WS路径: ' + lines[1]);
|
||
|
||
const url = `ws://127.0.0.1:${lines[0]}${lines[1]}`;
|
||
const t0 = Date.now();
|
||
const ws = new WebSocket(url);
|
||
const opened = await new Promise(res => {
|
||
const timer = setTimeout(() => res(false), 60000);
|
||
ws.addEventListener('open', () => { clearTimeout(timer); res(true); }, { once: true });
|
||
ws.addEventListener('error', () => { clearTimeout(timer); res(false); }, { once: true });
|
||
});
|
||
if (!opened) { log('FAIL: WebSocket 连不上(Chrome 调试端口可能已关闭或需重新开启 chrome://inspect)'); process.exit(0); }
|
||
log(`CDP 握手成功,耗时 ${Date.now() - t0}ms`);
|
||
|
||
let seq = 0; const pend = new Map();
|
||
ws.addEventListener('message', ev => {
|
||
let m; try { m = JSON.parse(ev.data); } catch { return; }
|
||
if (m.id && pend.has(m.id)) { const p = pend.get(m.id); pend.delete(m.id); m.error ? p.rej(new Error(m.error.message)) : p.res(m.result); }
|
||
else if (m.method) events.push(m);
|
||
});
|
||
const events = [];
|
||
const send = (method, params = {}, sid) => new Promise((res, rej) => {
|
||
const id = ++seq; pend.set(id, { res, rej });
|
||
const msg = { id, method, params }; if (sid) msg.sessionId = sid;
|
||
ws.send(JSON.stringify(msg));
|
||
});
|
||
|
||
const { product, protocolVersion } = await send('Browser.getVersion');
|
||
log(`浏览器: ${product} (CDP 协议 v${protocolVersion})`);
|
||
|
||
const { targetInfos } = await send('Target.getTargets');
|
||
const pages = targetInfos.filter(t => t.type === 'page');
|
||
log(`\n当前打开的标签页 ${pages.length} 个:`);
|
||
pages.forEach((t, i) => log(` ${i + 1}. ${t.title.slice(0, 40)} | ${t.url.slice(0, 80)}`));
|
||
|
||
// 挑一个闲鱼页面做读取能力演示
|
||
const target = pages.find(p => /goofish/i.test(p.url)) || pages[0];
|
||
if (target) {
|
||
const { sessionId } = await send('Target.attachToTarget', { targetId: target.targetId, flatten: true });
|
||
const r = await send('Runtime.evaluate', {
|
||
expression: `({url: location.href, title: document.title, readyState: document.readyState, bodyLen: document.body ? document.body.innerText.length : 0, loginState: document.body ? (document.body.innerText.includes('登录') ? '页面上出现"登录"字样' : '未见登录字样') : 'n/a'})`,
|
||
returnByValue: true,
|
||
}, sessionId);
|
||
log('\n读取能力验证(对目标页执行 JS 并取回结果):');
|
||
log(' ' + JSON.stringify(r.result.value, null, 2).replace(/\n/g, '\n '));
|
||
await send('Target.detachFromTarget', { sessionId });
|
||
}
|
||
ws.close();
|
||
log('\n结论: 调试通道可用。');
|
||
setTimeout(() => process.exit(0), 300);
|