0%

Chrome Profile 登录状态持久化问题排查总结

Chrome Profile 登录状态持久化问题排查总结

问题现象

启动 Chrome 自动化脚本时,日志显示”复用已有 Profile(登录状态将保留)”,但实际登录状态未保留。伴随 boss-go-chrome-profile 目录下大量文件被修改。

根本原因

核心问题:Chrome 单例机制

Chrome 单例机制:当系统中已有 Chrome 实例在运行时,新的 Chrome 进程(包括指定了 --user-data-dir 的)会忽略 user-data-dir 参数,直接附加到已有进程,并使用已有进程对应的 profile。

这导致:

  1. 脚本启动的 Chrome 实际使用的是系统默认 profile,而非指定的 boss-go-chrome-profile
  2. 登录信息写入的是系统默认 profile
  3. 下次脚本运行时,加载的是 boss-go-chrome-profile(无登录信息)

次要问题:强制终止导致 Cookies 未保存

使用 pkill -9Browser.close() 后立即终止进程,Chrome来不及将 cookies 写入磁盘。

关键发现过程

步骤 发现 验证方法
1 Cookies 文件从未更新 stat -f "%Sm" Cookies 时间戳不变
2 Session Storage 有 zhipin 数据 strings Session Storage/*.dat 发现 zhipin 域名
3 手动 open -a 登录可保持 排除 profile 本身问题
4 直接 spawn Chrome 二进制不行 spawn 方式启动的 Chrome 使用了错误 profile
5 open -a 方式启动可行 open -a 是 macOS 标准启动方式

解决方案

方案:使用 open -a 启动 Chrome

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// ❌ 错误方式 - 会被单例机制忽略
spawn('/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', [
'--user-data-dir=/path/to/profile',
'--profile-directory=Default'
], { detached: true });

// ✅ 正确方式 - 使用 macOS open 命令
spawn('open', [
'-a', 'Google Chrome',
'--args',
`--user-data-dir=${CONFIG.chromeUserDataDir}`,
'--profile-directory=Default',
'--remote-debugging-port=9222',
'--no-first-run',
'--no-default-browser-check'
], {
stdio: 'ignore',
detached: true
});

确保 Chrome 正常关闭(保留 Cookies)

1
2
3
4
5
6
7
8
9
10
11
async function closeChrome() {
try {
const client = await CDP({ port: 9222 });
const { Browser } = client;
await Browser.close(); // 优雅关闭,等待 cookies 写入磁盘
await client.close();
await wait(3000); // 等待 Chrome 充分关闭
} catch (e) {
// Chrome 已关闭
}
}

启动前确保没有残留 Chrome 进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
async function ensureChrome() {
// 使用 pgrep 检查是否有 Chrome 进程
const { execSync } = require('child_process');

try {
const result = execSync('pgrep -i "chrome" | wc -l', { encoding: 'utf8' });
const count = parseInt(result.trim(), 10);
if (count > 0) {
execSync('pkill -9 "Google Chrome"', { stdio: 'ignore' });
await wait(2000);
}
} catch (e) { }

// 然后启动 Chrome
await startChrome();
}

关键文件

  • scripts/chrome.js - Chrome 启动和关闭逻辑
  • scripts/boss-go.js - 主流程
  • scripts/browser.js - CDP 操作

验证步骤

  1. 确保无残留进程:pkill -9 "Google Chrome"; sleep 2
  2. 删除锁文件:rm -f profile/SingletonLock profile/SingletonSocket
  3. 运行脚本
  4. 登录 Boss 直聘,等待 3 秒
  5. 正常退出(或 Ctrl+C,让 closeChrome 执行)
  6. 重新运行,检查登录状态是否保留

相关资料

经验教训

  1. macOS 上使用 open -a 而非直接 spawn Chrome 二进制
  2. 强制终止会导致 cookies 丢失,必须使用优雅关闭
  3. 单例机制是根本原因,任何启动方式都需要先确保没有其他 Chrome 实例
  4. Session Storage 可能保存登录状态,而 Cookies 可能没有(取决于网站实现)