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

使用Playwright异步代码遇NotImplementedError:求原因分析与解决方案

问题分析与解决方案

根本原因

  1. 同步sleep阻塞事件循环:异步函数中使用了time.sleep()这个同步方法,会直接阻塞整个异步事件循环,导致Playwright的异步操作无法正常执行,最终触发NotImplementedError。
  2. 异常捕获类型错误:代码中捕获的PlaywrightTimeout并非Playwright实际抛出的超时异常类型,无法正确处理超时场景,导致错误未被拦截而暴露。
  3. 重复初始化Playwright实例:每次重试都重新创建async_playwright()上下文,不仅浪费资源,还可能因资源未正确释放引发异常。

修复后的代码

import asyncio
from playwright.async_api import async_playwright
from playwright._impl._errors import TimeoutError

async def get_html(url, selector, sleep=5, retries=3):
    html = None
    # 将Playwright实例初始化移到循环外
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        for i in range(1, retries+1):
            # 替换为异步sleep
            await asyncio.sleep(sleep * i)
            try:
                page = await browser.new_page()
                await page.goto(url)
                print(await page.title())
                html = await page.inner_html(selector)
                await page.close()
                break
            except TimeoutError:
                print(f"Timeout error on {url}, retry {i}/{retries}")
                await page.close()
                continue
        await browser.close()
    return html

关键修复点说明

  • 用await asyncio.sleep()替代time.sleep():异步sleep不会阻塞事件循环,保证Playwright的异步任务能正常调度。
  • 修正异常捕获类型:使用Playwright官方定义的TimeoutError,确保超时错误能被正确捕获并触发重试。
  • 复用Playwright和浏览器实例:将async_playwright()和browser的初始化移到循环外,避免重复创建资源,提升运行效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 13:25:01