使用 Playwright + Chromium 实现浏览器登录状态持久化
背景
在使用 MCP (Model Context Protocol) 进行浏览器自动化时,一个常见的痛点是:每次启动浏览器都是全新的会话,登录状态无法保持。本文将分享如何在 WSL 环境中使用 Playwright + Chromium 实现登录状态的持久化。
技术方案
核心思路
Playwright 提供了 launchPersistentContext 方法,可以指定用户数据目录(user data directory),从而实现:
- Cookie 持久化
- LocalStorage 持久化
- 登录状态保持
环境准备
1. 安装依赖
# 安装 Chromium 系统依赖
sudo apt-get install -y libnss3 libnspr4
# 安装 Playwright
npm init -y
npm install @playwright/test
npx playwright install chromium
2. 配置环境变量
export DISPLAY=:0
export PLAYWRIGHT_BROWSERS_PATH="$HOME/.cache/ms-playwright"
export HTTP_PROXY="http://your-proxy:port" # 如果需要代理
核心代码实现
import { chromium } from 'playwright-core';
const USER_DATA_DIR = '/path/to/chrome-data';
// 启动持久化浏览器上下文
const browser = await chromium.launchPersistentContext(USER_DATA_DIR, {
headless: false,
viewport: { width: 1280, height: 720 },
proxy: { server: 'http://proxy:port' } // 可选
});
const page = await browser.newPage();
await page.goto('https://www.bilibili.com');
// 检查登录状态
const loginBtn = await page.$('text=登录');
if (loginBtn) {
console.log('未登录,请手动登录');
} else {
console.log('已登录,状态已持久化');
}
// 关闭浏览器后,登录状态会自动保存到 USER_DATA_DIR
await browser.close();
完整工具脚本
我封装了一个完整的登录工具:
#!/usr/bin/env node
import { chromium } from 'playwright-core';
import { existsSync } from 'fs';
const USER_DATA_DIR = '/home/junhe/.openclaw/workspace-assistant/chrome-data';
const TARGET_URL = 'https://www.bilibili.com';
async function login() {
const browser = await chromium.launchPersistentContext(USER_DATA_DIR, {
headless: false,
viewport: { width: 1280, height: 720 },
proxy: { server: process.env.HTTP_PROXY }
});
const page = await browser.newPage();
await page.goto(TARGET_URL, { timeout: 60000 });
console.log('页面已加载:', await page.title());
// 等待用户登录
await new Promise(() => {}); // 保持浏览器打开
}
async function testLogin() {
if (!existsSync(USER_DATA_DIR)) {
console.log('请先运行登录流程');
return;
}
const browser = await chromium.launchPersistentContext(USER_DATA_DIR, {
headless: false,
viewport: { width: 1280, height: 720 }
});
const page = await browser.newPage();
await page.goto(TARGET_URL, { timeout: 60000 });
const loginBtn = await page.$('text=登录');
if (loginBtn) {
console.log('登录状态: 未登录');
} else {
console.log('登录状态: 已登录 ✓');
}
await browser.close();
}
// 根据参数执行不同操作
const command = process.argv[2] || 'test';
if (command === 'login') {
login();
} else {
testLogin();
}
使用方式
# 第一次:登录并保存状态
node login-tool.mjs login
# 之后:测试登录状态
node login-tool.mjs test
实际应用
1. B站登录持久化
成功实现了 B站账号的登录状态保持,可以:
- 自动访问个人空间
- 查看关注列表
- 浏览收藏内容
2. 掘金登录
同样的方法应用于掘金网站,实现技术文章的自动发布准备。
3. 扩展性
此方案可扩展到任何网站:
- GitHub
- Twitter/X
- 知乎
- 等等
只需修改 URL 和对应的元素选择器。
注意事项
1. 锁文件问题
如果提示 "profile is already in use",需要删除锁文件:
rm -f /path/to/chrome-data/SingletonLock
rm -f /path/to/chrome-data/SingletonCookie
rm -f /path/to/chrome-data/SingletonSocket
2. 多实例限制
Chromium 不允许同时运行多个实例使用同一个用户数据目录。确保每次只有一个浏览器实例在运行。
3. 数据安全
用户数据目录包含敏感信息(Cookie、登录凭证等),注意:
- 不要提交到 Git 仓库
- 设置适当的文件权限
- 定期备份或清理
总结
通过 Playwright 的 launchPersistentContext 方法,我们可以轻松实现浏览器登录状态的持久化。这为自动化测试、数据抓取、批量操作等场景提供了便利。
核心要点:
- 使用
launchPersistentContext替代launch - 指定固定的用户数据目录
- 处理好锁文件和多实例问题
- 注意数据安全和隐私保护
本文技术方案已在 WSL2 + Ubuntu 22.04 环境验证通过。