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

Python Playwright中select_option触发后如何等待表格更新完成?

解决Playwright中表格动态更新的检测问题

原代码依赖sleep才能获取正确结果,核心问题是没有等待表格内容真正完成更新,仅等待元素存在无法确保数据加载完毕。以下是符合Playwright设计理念的解决方案:

核心思路

  • 等待内容变化:选择地址前后对比目标行的内容,等待内容发生变更,确保表格已更新。
  • 利用Playwright断言:expect API会自动等待条件满足,无需手动设置等待时间。
  • 适配异步场景:提供异步版本代码,方便后续接入Scrapy的async API。

修改后的同步版本代码

from playwright.sync_api import sync_playwright, expect

ign = ["42,", "44,", *list(map(lambda x: f'{chr(x)},', range(ord("A"), ord("J"))))]

def run():
    with sync_playwright() as playwright:
        browser = playwright.chromium.launch(headless=False)
        context = browser.new_context()
        page = context.new_page()
        page.goto("https://checker.ofcom.org.uk/en-gb/broadband-coverage")
        
        # 处理cookie弹窗
        page.get_by_role("button", name="Reject optional cookies and close").click()
        
        # 输入并提交邮编
        page.get_by_placeholder("Postcode").fill("tn13 1xt")
        page.get_by_role("button", name="Set postcode").click()
        
        # 获取并过滤地址列表
        address_text = page.get_by_role("combobox", name="Select your address").inner_text()
        opts = sorted(address_text.split('\n')[1:])
        
        for opt in opts.copy():
            for ig in ign:
                if ig in opt:
                    try:
                        opts.remove(opt)
                    except ValueError:
                        print(f"already removed {opt}")
        print(opts)
        
        for opt in opts:
            # 记录当前Ultrafast行的内容
            current_content = page.get_by_role("row", name="Ultrafast").text_content()
            # 选择目标地址
            page.get_by_role("combobox", name="Select your address").select_option(label=opt)
            # 等待行内容发生变化,自动等待直到条件满足
            expect(page.get_by_role("row", name="Ultrafast")).not_to_have_text(current_content)
            # 获取更新后的内容
            updated_content = page.get_by_role("row", name="Ultrafast").text_content()
            print(f"status of Ultrafast for {opt}: {updated_content}")
        
        context.close()
        browser.close()

run()

异步版本(适配Scrapy async API)

import asyncio
from playwright.async_api import async_playwright, expect

ign = ["42,", "44,", *list(map(lambda x: f'{chr(x)},', range(ord("A"), ord("J"))))]

async def run():
    async with async_playwright() as playwright:
        browser = await playwright.chromium.launch(headless=False)
        context = await browser.new_context()
        page = await context.new_page()
        await page.goto("https://checker.ofcom.org.uk/en-gb/broadband-coverage")
        
        # 处理cookie弹窗
        await page.get_by_role("button", name="Reject optional cookies and close").click()
        
        # 输入并提交邮编
        await page.get_by_placeholder("Postcode").fill("tn13 1xt")
        await page.get_by_role("button", name="Set postcode").click()
        
        # 获取并过滤地址列表
        address_text = await page.get_by_role("combobox", name="Select your address").inner_text()
        opts = sorted(address_text.split('\n')[1:])
        
        for opt in opts.copy():
            for ig in ign:
                if ig in opt:
                    try:
                        opts.remove(opt)
                    except ValueError:
                        print(f"already removed {opt}")
        print(opts)
        
        for opt in opts:
            # 记录当前Ultrafast行的内容
            current_content = await page.get_by_role("row", name="Ultrafast").text_content()
            # 选择目标地址
            await page.get_by_role("combobox", name="Select your address").select_option(label=opt)
            # 等待行内容发生变化
            await expect(page.get_by_role("row", name="Ultrafast")).not_to_have_text(current_content)
            # 获取更新后的内容
            updated_content = await page.get_by_role("row", name="Ultrafast").text_content()
            print(f"status of Ultrafast for {opt}: {updated_content}")
        
        await context.close()
        await browser.close()

asyncio.run(run())

额外优化方案:监听网络请求

如果明确表格更新依赖的API接口,可以直接等待该请求完成后再读取内容,进一步提高可靠性:

# 同步版本示例
with page.expect_request_finished("**/api/coverage*") as request_info:
    page.get_by_role("combobox", name="Select your address").select_option(label=opt)
request = request_info.value
assert request.ok  # 确保请求成功

内容的提问来源于stack exchange,提问作者user676952

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 06:40:52