Python Playwright中select_option触发后如何等待表格更新完成?
解决Playwright中表格动态更新的检测问题
原代码依赖sleep才能获取正确结果,核心问题是没有等待表格内容真正完成更新,仅等待元素存在无法确保数据加载完毕。以下是符合Playwright设计理念的解决方案:
核心思路
- 等待内容变化:选择地址前后对比目标行的内容,等待内容发生变更,确保表格已更新。
- 利用Playwright断言:
expectAPI会自动等待条件满足,无需手动设置等待时间。 - 适配异步场景:提供异步版本代码,方便后续接入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
相关产品推荐
相关产品推荐

