v10.13 个人黑名单: person_blacklist表+卡片级预筛(姓+年龄匹配/全名精确/resumeNumber), 命中不开弹窗直接跳过; 已拉黑孟心如(23岁,用户2026-09-29指定)
This commit is contained in:
@@ -48,6 +48,30 @@ const CDP_PORT = process.env.CDP_PORT || '9222';
|
||||
const ACCOUNT = process.env.ACCOUNT || 'hr1';
|
||||
const TARGET_CITY = process.env.TARGET_CITY || '郑州';
|
||||
const COMPANY_BLACKLIST = ['合塑', '派卡']; // 从 workDetail 提取公司名命中即跳过
|
||||
|
||||
// ---------- 个人黑名单(v10.13, 2026-09-29)----------
|
||||
// person_blacklist 表:用户指定的候选人,命中即不开弹窗直接跳过
|
||||
// 匹配规则:① 姓名=全名(弹窗里能看到全名)② 卡片场景兜底:姓+年龄一致(如"孟女士"+23岁)
|
||||
// ③ resumeNumber 精确匹配(如有)
|
||||
let PERSON_BLACKLIST = [];
|
||||
function loadPersonBlacklist(db) {
|
||||
try {
|
||||
PERSON_BLACKLIST = db.prepare('SELECT resume_number, name, age FROM person_blacklist').all();
|
||||
if (PERSON_BLACKLIST.length) log(`个人黑名单已加载: ${PERSON_BLACKLIST.length} 人 [${PERSON_BLACKLIST.map(p => p.name).join('、')}]`);
|
||||
} catch (e) { PERSON_BLACKLIST = []; } // 表不存在等异常不阻塞主流程
|
||||
}
|
||||
function personBlackHit(cardName, cardAge, resumeNumber) {
|
||||
for (const p of PERSON_BLACKLIST) {
|
||||
if (p.resume_number && resumeNumber && p.resume_number === resumeNumber) return `${p.name}(精确ID)`;
|
||||
if (cardName && p.name && cardName === p.name) return p.name; // 弹窗全名精确
|
||||
// 卡片"姓+称谓"场景:孟女士/孟先生 的姓 == 黑名单人姓 且年龄一致
|
||||
if (cardName && cardAge != null && p.name && p.age === cardAge
|
||||
&& /^(.)(女士|先生)/.test(cardName) && cardName.charAt(0) === p.name.charAt(0)) {
|
||||
return `${p.name}(姓+年龄匹配)`;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const MAX_START_SKIP = 50;
|
||||
|
||||
// ---------- 工具 ----------
|
||||
@@ -349,6 +373,7 @@ async function scrapeZhaopin(maxCount = 20, fullMode = false, scoreOnly = false)
|
||||
if (!page) { console.log('ERROR: 未找到推荐页面(需在浏览器中打开 recommend 页)'); await browser.close(); process.exit(1); }
|
||||
|
||||
const db = initDB();
|
||||
loadPersonBlacklist(db); // v10.13:个人黑名单
|
||||
const existingIds = new Set(db.prepare('SELECT id FROM candidates').all().map(r => r.id));
|
||||
// 启动快速跳过用的卡片指纹(name|age|education|experience,来自历史 card_info)
|
||||
const storedCards = new Set(db.prepare("SELECT card_info FROM candidates WHERE card_info IS NOT NULL").all()
|
||||
@@ -446,6 +471,10 @@ async function scrapeZhaopin(maxCount = 20, fullMode = false, scoreOnly = false)
|
||||
const cardBlackHit = COMPANY_BLACKLIST.find(b => card.cardText && card.cardText.includes(b));
|
||||
if (cardBlackHit) { log(`🚫 [跳过-列表黑名单] ${card.name} | 卡片含"${cardBlackHit}"`); skipped++; currentDataIndex = await navigateToNextCard(page, currentDataIndex); continue; }
|
||||
|
||||
// v10.13:个人黑名单(卡片级:姓+年龄)——不开弹窗直接跳过
|
||||
const pBlackHit = personBlackHit(card.name, card.age, null);
|
||||
if (pBlackHit) { log(`🚫 [跳过-个人黑名单] ${card.name} ${card.age}岁 | 命中: ${pBlackHit}`); skipped++; currentDataIndex = await navigateToNextCard(page, currentDataIndex); continue; }
|
||||
|
||||
try {
|
||||
// 打开弹窗(v10.12:Playwright原生点击替代evaluate合成click——平台反自动化检测会
|
||||
// 对合成点击返回空白弹窗;原生点击走真实鼠标事件流 CDP Input.dispatchMouseEvent)
|
||||
|
||||
Reference in New Issue
Block a user