Puppeteer通过evaluate执行脚本获取cookie

本文探讨了在页面加载脚本并获取生成的Cookie时遇到的问题。通过使用Puppeteer的page.setContent方法设置cookie,直接读取document.cookie会触发访问权限错误。解决策略包括先跳转至一个网站再读取cookie。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 应用背景

通常我们希望在页面加载一些脚本然后获取脚本生成的cookie。这里考虑使用page.setContent方法,其中script标签内部包含设置cookie的代码。最后通过执行document.cookie来获取cookie。

(async () => {

    const browser = await puppeteer.launch({
        "executablePath": "路径",
        "headless": false
    });

        try {
            let page = await browser.newPage();
            await page.setContent("<script>...</script>")
            let cookie = await page.evaluate(() => document.cookie);
            console.log("cookie :" + cookie);
        } catch (e) {
            console.log(e);
        } finally{
            await browser.close();
        }
})();

2 产生的问题与解决方式

按1中设想方式,最终会产生如下错误。

Error: Evaluation failed: DOMException: Failed to read the 'cookie' property from 'Document': Access is denied for this document.
    at __puppeteer_evaluation_script__:1:17
    at __puppeteer_evaluation_script__:1:17
    at ExecutionContext.evaluateHandle 

由于使用访问页面后再获取执行document.cookie可以正常调用,因此变通方法可以通过增加goto调用 page.goto(“https://www.baidu.com/”); 跳转到某个页面后再次获取即可。

(async () => {

    const browser = await puppeteer.launch({
        "executablePath": "/Users/Hello/Documents/chrome-mac/Chromium.app/Contents/MacOS/Chromium",
        "headless": false
    });

        try {
            let page = await browser.newPage();
            await page.goto("https://www.baidu.com/");
            await page.setContent("<script>...</script>")
            let cookie = await page.evaluate(() => document.cookie);
            console.log("cookie :" + cookie);
        } catch (e) {
            console.log(e);
        } finally{
            await browser.close();
        }
})();
<think>我们正在讨论Puppeteer中的BrowserContext。根据引用[1]中的描述:-BrowserContext对应浏览器的一个上下文会话,具有独立的Session(cookie和cache独立不共享)。-一个BrowserContext可以包含多个Page(即多个标签页)。因此,BrowserContext的session(会话)在同一时间支持多个页面(Page)是完全没有问题的。每个Page代表一个标签页,它们共享同一个BrowserContext的session(即相同的cookie和缓存环境)。例如,我们可以通过以下代码在一个BrowserContext中创建多个页面:```javascriptconstbrowser=awaitpuppeteer.launch();constcontext=awaitbrowser.createIncognitoBrowserContext();//创建一个新的隐身模式上下文//在同一个上下文中创建两个页面constpage1=awaitcontext.newPage();constpage2=awaitcontext.newPage();//在两个页面上进行操作...```在这个例子中,`page1`和`page2`都属于同一个BrowserContext(即`context`),因此它们共享相同的session(cookie和缓存)。这意味着在一个页面中设置的cookie在另一个页面中也是可见的。所以,回答用户的问题:Puppeteer中的BrowserContext定义的session在同一时间支持多个页面(Page),这些页面共享同一个session。###补充说明-**session的共享**:在同一个BrowserContext中,所有页面共享相同的session。这意味着在一个页面中登录后,其他页面也会保持登录状态(因为cookie共享)。-**独立上下文**:不同的BrowserContext之间session是隔离的。例如,你可以在一个BrowserContext中登录用户A,在另一个BrowserContext中登录用户B,两者互不影响。###示例:多个页面共享session```javascriptconstpuppeteer=require('puppeteer');(async()=>{constbrowser=awaitpuppeteer.launch();constcontext=awaitbrowser.createBrowserContext();//创建两个页面constpage1=awaitcontext.newPage();constpage2=awaitcontext.newPage();//在第一个页面中设置cookieawaitpage1.setCookie({name:'test',value:'123',url:'https://example.com'});//在第二个页面中访问同一个网站,应该能拿到同一个cookieawaitpage2.goto('https://example.com');constcookies=awaitpage2.cookies();console.log(cookies);//会包含{name:'test',value:'123',...}awaitbrowser.close();})();```###注意事项-如果在一个BrowserContext中打开多个页面,它们会共享资源(如缓存),因此要注意资源使用情况。-每个页面都是独立的,但通过BrowserContext,它们可以互相通信(例如通过`page.exposeFunction`等)。§§相关问题§§1.如何在Puppeteer中创建多个独立的BrowserContext?2.如何管理同一个BrowserContext中的多个页面?3.在同一个BrowserContext中,多个页面之间的cookie是如何同步的?</think>### Puppeteer 中 BrowserContext 的页面支持机制 在 Puppeteer 中,**BrowserContext 定义的 session 支持同时存在多个页面(Page)**,这是其核心设计特性之一。根据引用[1]的描述: > "一个 BrowserContext 可以包含多个 Page" #### 关键特性说明: 1. **多页面支持** - 通过 `browserContext.newPage()` 方法可创建多个独立的页面标签页 - 每个 Page 对象对应一个浏览器标签页 - 示例代码: ```javascript const context = await browser.createIncognitoBrowserContext(); const page1 = await context.newPage(); // 第一个页面 const page2 = await context.newPage(); // 第二个页面 const page3 = await context.newPage(); // 第三个页面 ``` 2. **会话共享机制** - 同一 BrowserContext 下的所有页面**共享相同的会话环境**(包括 cookie、缓存和本地存储) - 在一个页面设置的 cookie 会自动同步到同 Context 的其他页面: ```javascript // 在 page1 设置 cookie await page1.setCookie({ name: 'session', value: '12345' }); // 在 page2 可读取相同 cookie const cookies = await page2.cookies(); console.log(cookies); // 包含 { name: 'session', value: '12345' } ``` 3. **并发操作能力** - 多个页面可**同时执行操作**(如并行加载不同 URL) - 通过 Promise.all() 实现并行控制: ```javascript await Promise.all([ page1.goto('https://example.com/page1'), page2.goto('https://example.com/page2'), page3.evaluate(() => { /* 执行脚本 */ }) ]); ``` 4. **资源隔离特性** - 不同 BrowserContext 之间会话**完全隔离**(如隐身模式) - 但同一 Context 内的多个页面共享资源: ```javascript // 创建两个独立的上下文 const context1 = await browser.createIncognitoBrowserContext(); const context2 = await browser.createIncognitoBrowserContext(); // 不同上下文的页面完全隔离 await context1.newPage().setCookie({name: 'test', value: 'A'}); await context2.newPage().setCookie({name: 'test', value: 'B'}); // 不会冲突 ``` #### 典型应用场景: 1. **多账号测试**:同一浏览器实例中用不同 Context 模拟多用户登录 2. **并行数据采集**:单 Context 内多个页面同时抓取不同页面 3. **工作流测试**:在共享会话的多个页面间测试认证状态传递 4. **性能对比**:相同环境下并行加载多个页面进行性能分析 > 注意:单个 BrowserContext 可创建的页面数量受系统资源限制,建议通过 `browserContext.close()` 及时释放不再使用的上下文[^1]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值