谷粒的泥坑

🌿谷粒的生活笔记 —— 在数字世界的泥坑中,播种代码、文字的种子,静待每一份热爱自然生长

Playwright实现录制登录、保存Cookie及自动登录

Playwright实现录制登录、保存Cookie及自动登录的完整指南

Playwright是一个强大的浏览器自动化工具,支持录制用户操作、保存登录状态以及复用Cookie实现自动登录。下面我将详细介绍在Node.js环境下如何使用Playwright实现这些功能。

一、录制登录操作并保存Cookie

1. 使用codegen录制登录过程

Playwright提供了codegen命令可以录制用户操作并生成代码:

1
npx playwright codegen --save-storage=auth.json https://example.com/login

执行此命令会:

  1. 打开浏览器和Playwright Inspector窗口
  2. 记录你在登录页面的所有操作
  3. 在关闭浏览器后,将cookie和本地存储信息保存到auth.json文件中

2. 手动编码实现登录并保存状态

如果需要更精细的控制,可以手动编写登录脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const { chromium } = require('playwright');

(async () => {
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();
const page = await context.newPage();

// 访问登录页面
await page.goto('https://example.com/login');

// 填写登录表单
await page.fill('#username', 'your_username');
await page.fill('#password', 'your_password');
await page.click('#login-button');

// 等待登录完成
await page.waitForNavigation();

// 保存登录状态到文件
await context.storageState({ path: 'auth.json' });

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

这种方法可以保存完整的浏览器上下文状态,包括cookies、localStorage和sessionStorage

二、使用保存的Cookie实现自动登录

1. 加载保存的状态文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const { chromium } = require('playwright');

(async () => {
const browser = await chromium.launch({ headless: false });

// 加载之前保存的登录状态
const context = await browser.newContext({
storageState: 'auth.json'
});

const page = await context.newPage();

// 直接访问需要登录的页面
await page.goto('https://example.com/dashboard');

// 验证是否已登录
await page.screenshot({ path: 'logged-in.png' });

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

通过storageState选项加载保存的状态文件,可以跳过登录步骤直接进入已认证状态

2. 直接操作Cookies

如果需要更精细地控制Cookies,可以手动操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const { chromium } = require('playwright');
const fs = require('fs');

(async () => {
// 从文件读取cookies
const cookies = JSON.parse(fs.readFileSync('cookies.json', 'utf-8'));

const browser = await chromium.launch();
const context = await browser.newContext();

// 添加cookies到上下文
await context.addCookies(cookies);

const page = await context.newPage();
await page.goto('https://example.com');

// 其他操作...

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

这种方法适合只需要cookies而不需要完整浏览器状态的场景

三、高级技巧与注意事项

1. Cookie的有效期管理

  • 检查cookie的expires属性,确保没有过期
  • 对于会话cookie(没有设置expires),需要在同一浏览器会话中使用

2. 处理动态内容

1
2
// 等待特定元素出现,确认登录成功
await page.waitForSelector('.user-avatar', { timeout: 5000 });

3. 多环境适配

1
2
3
4
5
6
7
// 可以根据不同环境加载不同的状态文件
const env = process.env.NODE_ENV || 'development';
const stateFile = `auth.${env}.json`;

const context = await browser.newContext({
storageState: fs.existsSync(stateFile) ? stateFile : undefined
});

4. 错误处理

1
2
3
4
5
6
try {
await page.goto('https://example.com/dashboard');
} catch (error) {
console.error('可能登录状态已失效:', error);
// 重新登录逻辑...
}

四、实际应用示例

1. 完整的登录状态保存与复用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
const { chromium } = require('playwright');
const fs = require('fs');
const path = require('path');

const STATE_PATH = path.join(__dirname, 'auth.json');

async function loginAndSaveState() {
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();
const page = await context.newPage();

try {
await page.goto('https://example.com/login');

// 登录操作
await page.fill('#username', 'your_username');
await page.fill('#password', 'your_password');
await page.click('#login');

// 等待登录完成
await page.waitForURL('https://example.com/dashboard');

// 保存状态
await context.storageState({ path: STATE_PATH });
console.log('登录状态已保存');

return true;
} catch (error) {
console.error('登录失败:', error);
return false;
} finally {
await browser.close();
}
}

async function useSavedState() {
if (!fs.existsSync(STATE_PATH)) {
console.log('没有找到保存的登录状态,需要先登录');
return;
}

const browser = await chromium.launch({ headless: false });
const context = await browser.newContext({
storageState: STATE_PATH
});
const page = await context.newPage();

try {
await page.goto('https://example.com/dashboard');
console.log('成功使用保存的状态登录');

// 执行需要登录的操作...

} catch (error) {
console.error('使用保存的状态失败:', error);
} finally {
await browser.close();
}
}

// 使用示例
(async () => {
const useSaved = await useSavedState();
if (!useSaved) {
await loginAndSaveState();
await useSavedState();
}
})();

五、常见问题解决

  1. 登录状态无效

    • 检查cookie是否过期
    • 确认网站没有额外的安全措施(如IP绑定)
    • 可能需要更新保存的状态文件
  2. 跨域问题

    • 确保cookie的domainpath设置正确
    • 对于跨域场景,可能需要手动设置cookie属性
  3. 页面元素定位问题

    • 使用Playwright的定位策略(如getByText, getByRole等)
    • 考虑使用page.pause()进行调试

通过以上方法,你可以轻松实现Playwright的录制登录、保存Cookie以及自动登录功能,大大提高自动化测试和爬虫开发的效率。