Files
zhaopin/skill/references/dual-account-setup.md
T
mzl92 e0d9c4e434 初始提交: 智联简历筛选系统v10(含Hermes每日自动化层)
- 硬性预筛门槛: 外贸经验必须(仅工作经历匹配), 培养类拦截, 毕业2020-2026, 年龄<=35
- 七维评分+动态阈值+打招呼纪律
- Hermes每日自动化: daily-runner(09:30-18:00)/daily-report/enforce-cutoff/stop-tasks
- v10.4: 每累计200人自动刷新页面
- 修正: CDP端口9222(反向隧道), 通知只发私聊(防串台), hr2任务禁用
- WSL端: cdp-tunnel.sh 浏览器工人守护
2026-08-26 22:55:08 +08:00

235 lines
9.7 KiB
Markdown
Executable File
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.
# 双账号筛选 — Chrome + Edge 方案 (v0.2 已实施)
## 背景
两个智联招聘账号同时筛选简历,扩大覆盖面和打招呼配额。
## 方案选型
| 对比项 | 双 Chrome 实例 | Chrome + Edge |
|--------|---------------|---------------|
| profile 隔离 | 手动 robocopy 一份 profile | **天然隔离**,各用各的 |
| 登录互踢风险 | 同浏览器同协议,有风险 | **不同浏览器,cookie 完全隔离,不会互踢** |
| 启动方式 | 要记哪个是哪个 | 桌面图标一目了然 |
| CDP 连接 | playwright connectOverCDP | **完全相同**,脚本零改动 |
| 脚本改动 | 零差异 | 零差异 |
**结论:Chrome + Edge 方案更优,已采用。**
## 架构
```
┌──────────────────────────────────────────────────────────┐
│ Linux (Hermes) │
│ │
│ batch-runner (ACCOUNT=hr1) ─CDP_PORT=9223──→ SSH 9223→9222 │
│ batch-runner (ACCOUNT=hr2) ─CDP_PORT=9225──→ SSH 9225→9224 │
│ │
│ recruitment.db (candidates.account 区分来源) │
└──────────────────────────────────────────────────────────┘
│ │
SSH 隧道 9223→9222 SSH 隧道 9225→9224
│ │
┌────────┴──────────┐ ┌────────┴──────────┐
│ Windows 桌面 │ │ Windows 桌面 │
│ Chrome (hr1) │ │ Edge (hr2) │
│ CDP :9222 │ │ CDP :9224 │
│ user-data-dir: │ │ user-data-dir: │
│ C:\temp\ │ │ C:\temp\ │
│ chrome-debug │ │ edge-debug │
└───────────────────┘ └───────────────────┘
```
## 端口映射
| 账号 | 浏览器 | Windows CDP | Linux 本地 | SSH 隧道 |
|------|--------|------------|-----------|---------|
| hr1 | Chrome | 9222 | 9223 | `sshpass -p 'xxx' ssh -fN -p 7022 -L 9223:127.0.0.1:9222 sshadmin@8.152.213.143` |
| hr2 | Edge | 9224 | 9225 | `sshpass -p 'xxx' ssh -fN -p 7022 -L 9225:127.0.0.1:9224 sshadmin@8.152.213.143` |
## Edge 配置
### 安装路径(已确认)
```
C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
```
### user-data-dir
```
C:\temp\edge-debug
```
首次使用无需从默认 profile 复制,Edge 会在该目录创建新 profile。手动登录第二个智联账号后,登录态自动保存在此目录。
### 桌面快捷方式(已创建 ✅)
桌面路径:`C:\Users\sshadmin.WIN-3NKO8I5R9IJ\Desktop\Edge Debug Mode.lnk`
创建方法(通过 scp + cscript):
1. 本地写 VBS 脚本到 `/tmp/mksc.vbs`
2. `scp /tmp/mksc.vbs sshadmin@8.152.213.143:\"C:/temp/mksc.vbs\"`
3. `sshpass -p 'xxx' ssh -p 7022 sshadmin@8.152.213.143 "cscript //nologo C:\\temp\\mksc.vbs"`
> ⚠️ 桌面实际路径是 `C:\Users\sshadmin.WIN-3NKO8I5R9IJ\Desktop`(非 `Administrator`),通过 `ws.SpecialFolders("Desktop")` 自动获取正确路径。
### ⚠️ CDP 启动方式
**SSH 会话内直接启动 Edge → CDP 端口不可达**(Windows Session 隔离)。
**解决方案:schtasks 计划任务**
```powershell
# 注册(只需一次)
schtasks /Create /IT /RU Administrator /TN LaunchEdgeDebug /TR "\"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe\" --remote-debugging-port=9224 --user-data-dir=C:\temp\edge-debug" /SC ONLOGON /RL HIGHEST
# 每次启动
schtasks /Run /TN LaunchEdgeDebug
```
`/IT` = Interactive,在交互式桌面 session 中运行。详见 `windows-remote-scraping.md`。
## 数据库改造(已完成 ✅)
```sql
ALTER TABLE candidates ADD COLUMN account TEXT DEFAULT 'hr1';
ALTER TABLE greet_log ADD COLUMN account TEXT DEFAULT 'hr1';
CREATE INDEX idx_cand_account ON candidates(account);
```
现有 2817 条 hr1 数据自动标记 `hr1`。脚本通过 `ACCOUNT` 环境变量写入该字段,查询时按 `account` 过滤。
## 脚本改造(已完成 ✅)
### zhaopin-scrape.js v9.2
改动点:
1. `const ACCOUNT = process.env.ACCOUNT || 'hr1'` — 文件顶部
2. CREATE TABLE 加 `account TEXT NOT NULL DEFAULT 'hr1'`
3. `upsertCandidate()` — INSERT 加 account 列和参数
4. `logGreet()` — INSERT 加 account 列和参数
5. `getExistingFingerprints()` — `WHERE account = ?` 过滤
6. 启动快速跳过指纹加载 — `WHERE account = ?` 过滤
### batch-runner.js v2 (多账号版)
改动点:
1. `ACCOUNT`/`CDP_PORT`/`TARGET_CITY` 均从环境变量读取(默认 hr1/9223/郑州)
2. `runBatch()` 传 `ACCOUNT=xxx` 给子进程
3. `generateBatchReport()` — 按 account 过滤
4. `generateFinalReport()` — 所有 13 处 SQL 加 `WHERE account = ?`
5. `getDbCount()` — 按 account 过滤
6. 汇报标题带 `[hr1]`/`[hr2]` 标识
### 运行方式
```bash
# hr1(Chrome)
ACCOUNT=hr1 CDP_PORT=9223 node zhaopin-scrape.js 50
ACCOUNT=hr1 CDP_PORT=9223 nohup node batch-runner.js > /tmp/batch-runner-hr1.log 2>&1 &
# hr2(Edge)
ACCOUNT=hr2 CDP_PORT=9225 node zhaopin-scrape.js 50
ACCOUNT=hr2 CDP_PORT=9225 nohup node batch-runner.js > /tmp/batch-runner-hr2.log 2>&1 &
```
## Cron 定时任务(已创建 ✅)
| 任务 | 时间 | 账号 | 说明 |
|------|------|------|------|
| 工作日简历筛选 hr1 | 周一至周五 09:50 | hr1/Chrome/9223 | 原 cron 更新,加 ACCOUNT=hr1 |
| 工作日简历筛选 hr2 | 周一至周五 09:55 | hr2/Edge/9225 | 新建,错开 5 分钟避免 DB 锁争用 |
两个任务错开 5 分钟,避免同时启动时的数据库竞争。各自独立汇报到飞书群。
## 汇报规则
两个账号**各自独立汇报**,标题带 `[hr1]`/`[hr2]` 标识。`recruitment-report` 查询时按 `account` 过滤。如需汇总两个账号,去掉 account 过滤条件。
## SSH 隧道保活配置(2026-06-01 修复)⚠️ 关键
SSH 隧道频繁断连的根因:**客户端和服务端都没有心跳保活**。空闲连接被网络/NAT 丢弃后,batch-runner 的 `getChatCount()` 读到 null,误判为"聊天耗尽"并发群汇报。
**客户端保活(Linux `~/.ssh/config`):**
```
Host windows-hr
HostName 8.152.213.143
Port 7022
User sshadmin
ServerAliveInterval 15
ServerAliveCountMax 3
TCPKeepAlive yes
ExitOnForwardFailure yes
StrictHostKeyChecking no
```
**服务端保活(Windows `C:\ProgramData\ssh\sshd_config`):**
```
TCPKeepAlive yes
ClientAliveInterval 30
ClientAliveCountMax 3
```
修改后需重启 sshd:`net stop sshd && net start sshd`
**两端必须同时配置**,仅客户端保活在 Windows OpenSSH 上不可靠。
### 建隧道命令
```bash
# 外网连接(通过内网穿透),需 sshpass 密码认证
sshpass -p 'xxx' ssh -fN -p 7022 -L 9223:127.0.0.1:9222 sshadmin@8.152.213.143
sshpass -p 'xxx' ssh -fN -p 7022 -L 9225:127.0.0.1:9224 sshadmin@8.152.213.143
```
### 验证隧道
```bash
ss -tlnp | grep -E "9223|9225" # 确认端口监听
curl -s http://127.0.0.1:9223/json/version | head -1 # 确认 CDP 可达
curl -s http://127.0.0.1:9225/json/version | head -1
```
### 隧道守护脚本(自动重连)
心跳保活只能降低断连概率,无法 100% 防止。`ssh-tunnel-watchdog.sh` 作为兜底,每 10 秒检测端口,断了自动重建:
```bash
# 启动(与 batch-runner 同时运行)
nohup /home/kt/scripts/ssh-tunnel-watchdog.sh > /tmp/ssh-tunnel-watchdog.log 2>&1 &
```
脚本路径:`/home/kt/scripts/ssh-tunnel-watchdog.sh`
监控端口:9223(hr1)、9225(hr2)
日志:`/tmp/ssh-tunnel-watchdog.log`(仅断连重连时有输出)
## batch-runner.js 聊天耗尽验证机制(2026-06-01 新增)
batch-runner.js 现在内置三层防护,防止误判"聊天耗尽":
### 1. getChatCount() 区分 CDP 状态
- 返回数字:正常读取到聊天次数
- 返回 `null`:CDP 可达但页面读取失败(弹窗遮挡等)
- 返回 `'cdp_down'`:CDP 端口不通(隧道断开/浏览器关闭)
- 通过 `net.createConnection` 先探测端口,5秒超时
### 2. verifyChatExhausted(reason) 二次确认
所有 5 个判定点(启动、主循环、子进程 chat_empty、批次后检查×2)都调用此函数:
- CDP 不通 → 等待 30 秒重试,连续 3 次 CDP 不通 → 判定"连接异常"(**不发**最终汇报)
- 读到 0 → 连续 3 次确认后才判定真正耗尽
- 读到 >0 → 判定误判,返回剩余次数继续运行
### 3. stopReason 控制最终汇报
- `chat_empty`:聊天真正耗尽 → ✅ 发最终汇报
- `cdp_down`:连接异常 → ❌ **不发**汇报,只发"CDP 连接断开"错误通知
- `normal`:正常结束 → 不发汇报
## 日常启动流程
1. Windows 桌面:双击「Chrome Debug」→ 打开智联推荐页(hr1)
2. Windows 桌面:双击「Edge Debug Mode」→ 打开智联推荐页(hr2)
3. Linux:确认两条 SSH 隧道都通(`ss -tlnp | grep -E "9223|9225"` + `curl http://127.0.0.1:9223/json/version`)
4. Linux:启动隧道守护(`nohup /home/kt/scripts/ssh-tunnel-watchdog.sh > /tmp/ssh-tunnel-watchdog.log 2>&1 &`)
5. Linux:两个 batch-runner 并行启动(或等 cron 自动启动)
## 已知问题
1. ~~SSH 隧道不稳定~~(2026-06-01 已修复:双向心跳保活)
2. ~~CDP 连接失败与聊天耗尽共用退出路径~~(2026-06-01 已修复:verifyChatExhausted + stopReason)