Playwright实现录制登录、保存Cookie及自动登录的完整指南
Playwright是一个强大的浏览器自动化工具,支持录制用户操作、保存登录状态以及复用Cookie实现自动登录。下面我将详细介绍在Node.js环境下如何使用Playwright实现这些功能。
一、录制登录操作并保存Cookie
1. 使用codegen录制登录过程
Playwright提供了codegen
命令可以录制用户操作并生成代码:
1
| npx playwright codegen --save-storage=auth.json https://example.com/login
|
执行此命令会:
- 打开浏览器和Playwright Inspector窗口
- 记录你在登录页面的所有操作
- 在关闭浏览器后,将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 () => { const cookies = JSON.parse(fs.readFileSync('cookies.json', 'utf-8')); const browser = await chromium.launch(); const context = await browser.newContext(); 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(); } })();
|
五、常见问题解决
登录状态无效:
- 检查cookie是否过期
- 确认网站没有额外的安全措施(如IP绑定)
- 可能需要更新保存的状态文件
跨域问题:
- 确保cookie的
domain
和path
设置正确
- 对于跨域场景,可能需要手动设置cookie属性
页面元素定位问题:
- 使用Playwright的定位策略(如
getByText
, getByRole
等)
- 考虑使用
page.pause()
进行调试
通过以上方法,你可以轻松实现Playwright的录制登录、保存Cookie以及自动登录功能,大大提高自动化测试和爬虫开发的效率。