我的个人博客我的个人博客
首页
技术指南
首页
技术指南
  • Puppeteer 教程

    • Puppeteer 登录态传递指南

Puppeteer 登录态传递指南

在使用 Puppeteer 进行自动化测试或爬虫开发时,经常需要处理登录状态。每次运行脚本都重新登录不仅效率低下,还可能触发网站的安全验证机制(如验证码)。本文介绍几种常见的 Puppeteer 登录态传递方法。

方法一:使用 Cookies(最常用)

大多数网站使用 Cookies 来维持用户的登录会话。我们可以登录一次,保存 Cookies,然后在后续的脚本中加载这些 Cookies。

1. 获取并保存 Cookies

const puppeteer = require('puppeteer');
const fs = require('fs');

(async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  
  // 1. 访问登录页面并手动/自动登录
  await page.goto('https://example.com/login');
  // 这里假设你已经完成了登录操作,比如等待某个登录后的元素出现
  await page.waitForSelector('.dashboard'); 

  // 2. 获取当前页面的 Cookies
  const cookies = await page.cookies();

  // 3. 将 Cookies 保存到文件
  fs.writeFileSync('./cookies.json', JSON.stringify(cookies, null, 2));

  await browser.close();
})();

2. 加载 Cookies

const puppeteer = require('puppeteer');
const fs = require('fs');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // 1. 读取之前保存的 Cookies
  if (fs.existsSync('./cookies.json')) {
    const cookiesString = fs.readFileSync('./cookies.json');
    const cookies = JSON.parse(cookiesString);
    
    // 2. 将 Cookies 设置到当前页面
    await page.setCookie(...cookies);
  }

  // 3. 访问需要登录才能看到的页面
  await page.goto('https://example.com/dashboard');
  
  // 验证是否登录成功
  // ...

  await browser.close();
})();

方法二:使用 LocalStorage / SessionStorage

有些现代 Web 应用(SPA)将 JWT Token 存储在 localStorage 或 sessionStorage 中。

1. 获取并保存 LocalStorage

// 在登录成功后
const localStorageData = await page.evaluate(() => {
  let json = {};
  for (let i = 0; i < localStorage.length; i++) {
    const key = localStorage.key(i);
    json[key] = localStorage.getItem(key);
  }
  return json;
});

fs.writeFileSync('./localstorage.json', JSON.stringify(localStorageData, null, 2));

2. 恢复 LocalStorage

注意:需要在访问页面之前或者访问页面后立即注入 LocalStorage,这通常比 Cookies 麻烦一些,因为 localStorage 依附于域名。通常需要先 page.goto 到目标域名(哪怕是 404 页面),然后执行 evaluate 写入数据,再刷新或跳转。

await page.goto('https://example.com/404'); // 先跳转到同域页面

const localStorageData = JSON.parse(fs.readFileSync('./localstorage.json'));

await page.evaluate((data) => {
  for (const key in data) {
    localStorage.setItem(key, data[key]);
  }
}, localStorageData);

await page.goto('https://example.com/dashboard');

方法三:复用 User Data Dir

Chrome 允许指定用户数据目录,这样所有的浏览器数据(Cookies, LocalStorage, 缓存等)都会被自动保存和读取。

const browser = await puppeteer.launch({
  headless: false,
  userDataDir: './my-user-data' // 指定数据存储目录
});
  • 优点:完全模拟真实用户行为,无需手动处理 Cookies。
  • 缺点:userDataDir 可能会很大;不适合并发运行多个隔离的实例。

总结

方法适用场景复杂度
Cookies传统服务端 Session,大多数网站中等
LocalStorageJWT Token 存储在前端的 SPA中等(需注意注入时机)
User Data Dir需要持久化所有浏览器状态低

推荐优先尝试 Cookies 注入的方法,它既轻量又稳定。