v10.6 阻碍即停(通用): 弹窗有效性核查(缺姓名或全部结构信号=无效页, 不入库)→熔断; runner二次核查确认→私聊告警+停止(platform_blocked状态); 历史662条限额样本回测100%命中/正常简历0误判
This commit is contained in:
@@ -253,7 +253,16 @@ async function extractModalData(page) {
|
||||
const cm = (logsCountEl.innerText || '').match(/\((\d+)条\)/);
|
||||
if (cm) staffLogCount = parseInt(cm[1], 10);
|
||||
}
|
||||
// ===== 阻碍即停:弹窗有效性核查(v10.6 通用机制)=====
|
||||
// 正常简历弹窗:有姓名+年龄/学历等结构信号、内容较长、含标准段落
|
||||
// 异常弹窗(限额页/提示页/空数据):短文案、无结构信号
|
||||
// 触发条件:缺姓名 或 缺全部结构信号(年龄/学历/经验/教育段/工作段)——即"这不是一份简历"
|
||||
const hasName = !!(nameMatch && nameMatch[1] && nameMatch[1].trim() && !/提示|通知|警告|限额|上限/.test(nameMatch[1]));
|
||||
const hasStructure = !!(ageMatch || eduMatch || expMatch || eduSection ||
|
||||
section('工作经历', '教育经历|个人优势|专业技能|语言能力|证书|打电话|打招呼'));
|
||||
const modalBlocked = !hasName || !hasStructure;
|
||||
return {
|
||||
modalBlocked,
|
||||
staffLogCount,
|
||||
name: nameMatch ? nameMatch[1].trim() : '',
|
||||
age: ageMatch ? parseInt(ageMatch[1], 10) : null,
|
||||
@@ -442,6 +451,12 @@ async function scrapeZhaopin(maxCount = 20, fullMode = false, scoreOnly = false)
|
||||
if (refreshed) { await closeModal(page); log('页面已刷新(列表变化),重扫'); currentDataIndex = null; continue; }
|
||||
|
||||
const data = await extractModalData(page);
|
||||
// v10.6 阻碍即停:弹窗不是有效简历(限额/提示页/空数据)→ 不入库,立即熔断
|
||||
if (data?.modalBlocked) {
|
||||
const snippet = (data.rawText || '').split('\n').filter(Boolean).slice(0, 3).join(' / ').slice(0, 120);
|
||||
await closeModal(page);
|
||||
return stop(`🚨 ALERT: 弹窗无有效简历数据(可能触发平台限制),弹窗内容: ${snippet || '(空)'}`);
|
||||
}
|
||||
if (!data?.name) { await closeModal(page); log('数据提取失败'); errors++; currentDataIndex = await navigateToNextCard(page, currentDataIndex); continue; }
|
||||
|
||||
await humanBrowseModal(page);
|
||||
|
||||
Reference in New Issue
Block a user