Python Playwright点击新标签页后BrowserContext.pages长度不匹配问题
Playwright点击新标签页后BrowserContext.pages未即时更新的问题
问题描述
使用Python Playwright 1.31.1时,点击页面中打开新标签页的链接后,BrowserContext.pages返回的列表长度未即时增加。运行简化代码后,第二个打印输出应为2但实际显示1;调用new_page()打开第三个页面时,长度直接从1跳至3(正确值)。尝试监听Page和Context事件也无法捕获第二个页面,询问是否为Playwright的预期行为。
示例代码
# Using playwright 1.31.1 from playwright.sync_api import sync_playwright from time import sleep with sync_playwright() as pw: browser = pw.chromium.launch( executable_path = 'C:/Program Files/Google/Chrome/Application/chrome.exe', headless=False) ctx = browser.new_context() page = ctx.new_page() print('1. Number of pages', len(ctx.pages)) page.goto("https://www.dofactory.com/html/target/blank") # Click link which will open new page. g = page.locator('.mt-20').get_by_text('google') g.click() sleep(5) print('2. Number of pages (should be 2)', len(ctx.pages)) # Open then close a new page. ctx.new_page() sleep(5) print('3. Number of pages (should be 3)', len(ctx.pages)) ctx.pages[-1].close() sleep(5) print('4. Number of pages (should be 2)', len(ctx.pages))
运行输出
- Number of pages 1
- Number of pages (should be 2) 1
- Number of pages (should be 3) 3
- Number of pages (should be 2) 2
解答
这不是Playwright的预期行为,核心问题在于页面注册的同步时机:
- 点击链接打开新页面是浏览器异步执行的操作,Playwright需要时间将新页面实例注册到
BrowserContext中。sleep(5)是固定时长等待,无法保证Playwright完成页面注册,因此此时ctx.pages还未更新。 - 调用
ctx.new_page()是主动触发页面创建,Playwright会立即将新页面实例加入ctx.pages,所以长度能即时更新。
正确处理方式
不要依赖sleep或直接读取ctx.pages,而是通过监听BrowserContext的page事件等待新页面创建完成,确保精准同步页面生命周期。修改后的代码如下:
from playwright.sync_api import sync_playwright with sync_playwright() as pw: browser = pw.chromium.launch( executable_path='C:/Program Files/Google/Chrome/Application/chrome.exe', headless=False ) ctx = browser.new_context() page = ctx.new_page() print('1. Number of pages', len(ctx.pages)) page.goto("https://www.dofactory.com/html/target/blank") # 监听context的page事件,等待新页面创建完成 with ctx.expect_page() as new_page_info: page.locator('.mt-20').get_by_text('google').click() new_page = new_page_info.value # 获取新页面实例 print('2. Number of pages (should be 2)', len(ctx.pages)) # 后续操作 ctx.new_page() print('3. Number of pages (should be 3)', len(ctx.pages)) ctx.pages[-1].close() print('4. Number of pages (should be 2)', len(ctx.pages))
说明
ctx.expect_page()会阻塞直到新页面被创建并注册到context中,此时ctx.pages会包含新页面,长度正确更新为2。- 这种方式比
sleep更可靠,能适配不同的页面加载速度,避免因网络或渲染延迟导致的不同步问题。
内容的提问来源于stack exchange,提问作者COB
相关产品推荐
相关产品推荐

