Playwright点击Cookie按钮+添加Cookie仍无法移除Banner的问题
问题
我用Playwright做网站爬取,需要处理Cookie授权,但碰到两个异常:
- 点击Cookie接受按钮后,获取的HTML里同时有Cookie横幅文本和页面内容,导致Cheerio没法正常访问页面内容:
await page.waitForSelector('#cmp') await page.locator('#cmp').click()
- 如果点击按钮后额外添加Cookie(不管是自动获取后添加还是手动添加),获取的HTML里只有Cookie横幅内容,没有页面内容:
await page.waitForSelector('#cmp') await page.locator('#cmp').click() const cookies = await context.cookies() //点击按钮后能看到所有已添加的Cookie await context.addCookies(cookies)
实际可视化测试时,浏览器里Cookie横幅已经关闭,页面内容正常,但获取的HTML还是有横幅;把这个HTML在浏览器打开时,横幅又消失了。完整代码如下:
const getHtml = () => { const browser = await {chromium}["chromium"].launch({headless: false}); const context = await browser.newContext(); const page = await context.newPage() await page.goto(url); await page.waitForLoadState("networkidle"); await page.waitForSelector('#cmp') await page.locator('#cmp').click() const cookies = await context.cookies() //点击按钮后能看到所有已添加的Cookie await context.addCookies(cookies) // 等待主内容元素出现 await page.waitForSelector(("section[aria-labelledby='some']")) const html = await page.content(); await context.close(); await browser.close(); return html; }
解决方案
1. 修复Cookie横幅的等待逻辑
点击接受按钮后,不要只等待主内容元素,必须等待Cookie横幅从DOM中隐藏或移除,确保页面彻底完成更新:
// 点击接受按钮后,等待横幅元素消失 await page.waitForSelector('#cmp', { state: 'hidden' });
多数Cookie横幅点击后会通过CSS隐藏或直接从DOM删除,用state: 'hidden'能确保它不再存在于页面结构中,避免HTML残留相关内容。
2. 移除冗余的Cookie添加操作
你不需要手动添加已存在的Cookie,context.cookies()获取的是当前上下文已生效的Cookie,再次调用addCookies会触发冗余操作,甚至导致页面异常重渲染,这就是只显示横幅内容的原因。直接删除以下两行代码:
// 删掉这两行冗余代码 const cookies = await context.cookies() await context.addCookies(cookies)
3. 优化页面加载等待策略
networkidle的等待逻辑不够精准,建议结合页面加载阶段调整goto的等待参数:
// 等待DOM内容加载完成再执行后续操作 await page.goto(url, { waitUntil: 'domcontentloaded' }); // 或者等待页面所有资源加载完成 await page.goto(url, { waitUntil: 'load' });
4. 修正代码语法错误
原代码中getHtml函数遗漏了async关键字,会导致执行报错,必须补上:
const getHtml = async () => { // 添加async关键字 // ... 其余代码 }
最终修正后的完整代码
const getHtml = async () => { const browser = await chromium.launch({headless: false}); const context = await browser.newContext(); const page = await context.newPage(); // 等待DOM内容加载完成 await page.goto(url, { waitUntil: 'domcontentloaded' }); // 等待Cookie横幅出现并点击 await page.waitForSelector('#cmp'); await page.locator('#cmp').click(); // 等待Cookie横幅彻底消失 await page.waitForSelector('#cmp', { state: 'hidden' }); // 等待主内容元素加载完成 await page.waitForSelector("section[aria-labelledby='some']"); const html = await page.content(); await context.close(); await browser.close(); return html; }
内容的提问来源于stack exchange,提问作者learncode
相关产品推荐
相关产品推荐

