Files
zhaopin/scripts/login-qrcode.js
T

88 lines
3.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* 登录二维码获取器 v1.0(2026-08-27)
* 用法:node login-qrcode.js <port> <输出png路径>
*
* 流程:连CDP → 找登录页tab(没有则刷新推荐页触发跳转)→ 截取二维码区域的图片
* 智联登录页二维码是 canvas 或 img 动态渲染,直接整页截图最稳(剪裁左半部分登录卡片区)。
*/
const path = require('path');
function tryRequire(names) {
for (const n of names) { try { return require(n); } catch (_) {} }
throw new Error('无法加载 playwright-core');
}
const { chromium } = tryRequire([process.env.PWCORE_PATH, 'playwright-core'].filter(Boolean));
const PORT = process.argv[2] || '9222';
const OUT = process.argv[3] || `/tmp/zhaopin-login-qr-${PORT}.png`;
(async () => {
const b = await chromium.connectOverCDP(`http://127.0.0.1:${PORT}`);
let p = b.contexts()[0]?.pages().find(x => /passport\.zhaopin\.com/.test(x.url()));
// v1.1(2026-10-15):登录态预检——不在登录页且推荐页有卡片 = 已登录,无需发码
if (!p) {
const rec = b.contexts()[0]?.pages().find(x => /rd\d?\.zhaopin\.com/.test(x.url()));
if (rec) {
const logged = await rec.evaluate(() =>
!location.href.includes('passport') && document.querySelectorAll('.recommend-item').length > 0
).catch(() => false);
if (logged) { console.log('ALREADY_LOGGED_IN'); process.exit(0); } // 特殊退出码0+标记:已登录
}
// 找推荐页tab刷新,触发跳转到登录页
p = rec || b.contexts()[0]?.pages()[0];
if (!p) { console.error('NO_PAGE'); process.exit(1); }
await p.reload({ waitUntil: 'domcontentloaded', timeout: 60000 }).catch(() => {});
await new Promise(r => setTimeout(r, 4000));
// 刷新后可能跳到登录页
if (!/passport\.zhaopin\.com/.test(p.url())) {
await p.goto('https://passport.zhaopin.com/org/login', { waitUntil: 'domcontentloaded', timeout: 60000 }).catch(() => {});
await new Promise(r => setTimeout(r, 4000));
}
} else {
// 已在登录页:强制 reload 拿新二维码(页面上停留的旧码可能已过期)
await p.reload({ waitUntil: 'domcontentloaded', timeout: 60000 }).catch(() => {});
await new Promise(r => setTimeout(r, 4000));
}
console.log('PAGE:', p.url().slice(0, 90));
// v1.1:确认真的在登录页(防止误把推荐页/其他页面截图当二维码发出去)
if (!/passport\.zhaopin\.com/.test(p.url())) {
console.error('NOT_LOGIN_PAGE'); process.exit(1);
}
// 等二维码出现(canvas 或 img.qr / 二维码容器,多选择器兜底)
const qrSel = [
'canvas', // 智联登录二维码多为 canvas 绘制
'img[src*="qr"]',
'.qrcode', '.qr-code', '.login-qr', '[class*="qr" i]',
'.zp-qr', '#qr', '[id*="qr" i]',
];
let el = null;
for (let i = 0; i < 10 && !el; i++) {
for (const s of qrSel) {
el = await p.$(s).catch(() => null);
if (el) {
// 校验尺寸:太小的 canvas 可能是图标
const box = await el.boundingBox().catch(() => null);
if (!box || box.width < 100) { el = null; continue; }
break;
}
}
if (!el) await new Promise(r => setTimeout(r, 1000));
}
let shotPath = OUT;
if (el) {
await el.screenshot({ path: OUT }).catch(async () => { await p.screenshot({ path: OUT }); });
console.log('QR_ELEMENT_SHOT');
} else {
// v1.1(2026-10-15):删掉整页截图兜底——找不到二维码元素就报错,
// 不许把非二维码图片(登录页全屏/推荐页截图)当二维码发出去(用户10-15反馈)
console.error('NO_QR_ELEMENT');
process.exit(1);
}
console.log('SAVED:', OUT);
process.exit(0);
})().catch(e => { console.error('ERR:', String(e).slice(0, 150)); process.exit(1); });