使用 Playwright + Chromium 实现浏览器登录状态持久化

14 阅读3分钟

使用 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 环境验证通过。