You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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))

运行输出

  1. Number of pages 1
  2. Number of pages (should be 2) 1
  3. Number of pages (should be 3) 3
  4. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 08:33:25