报错:playwright._impl._api_types.Error: It looks like you are using Playwright Sync API insi

问题描述

在正常使用playwright串行接口时报错:playwright._impl._api_types.Error: It looks like you are using Playwright Sync API inside the asyncio loop.
Please use the Async API instead.
我个人是在自己写一个用playwright实现的web agent项目(webarena)相关时,使用脚本运行同一个playwright环境,如果之前有超时错误没有退出环境,又启动了playwright环境,此时它会认为你是想要一次性启动多个浏览器,所以会出现这个报错。原项目的代码比较复杂,就大致复现一下这个错误记录一下。

复现

from playwright.sync_api import (
    sync_playwright,
)
class Env:
    def __init__(self) -> None:
        pass

    def setup(self):
        self.context_manager = sync_playwright()
        self.playwright = self.context_manager.__enter__()
    
    def close(self):
        self.context_manager.__exit__()

env = Env()

# 循环执行某类浏览器任务,我们假设第一次执行任务顺利,第二次执行任务失败
for i in range(0,3):
    print(f"为第{i+1}次任务初始化浏览器环境。")
    env.setup() # 假设每次执行任务前都要初始化环境
    try:
        print(f"执行第{i+1}次任务中...")
        if i == 0:
            # 执行任务成功
            print(f"第{i+1}次任务执行成功!")
        elif i == 1:
            # 执行任务失败,抛出某异常
            raise Exception(f"第{i+1}次任务失败!")
        print("关闭浏览器环境。\n")
        env.close()
    except Exception as e:
        import traceback
        print(traceback.format_exc())
        print(e)

上面这个demo是一个简化的复现:

  • 每次执行任务时多要设置(初始化)浏览器环境
  • 若执行成功,则顺利关闭浏览器环境
  • 若失败,则任务会抛出某异常(一般是访问网站超时),异常处理里却忽略了关闭浏览器环境,这就导致执行下一个任务时,原来的浏览器还没有关闭,程序又要新开一个,但用的是串行的接口,就会出现提到的错误。

运行这个demo会输出:

为第1次任务初始化浏览器环境。
执行第1次任务中...
第1次任务执行成功!
关闭浏览器环境。

为第2次任务初始化浏览器环境。
执行第2次任务中...
Traceback (most recent call last):
  File "d:\vs_code_projects\test2\d.py", line 28, in <module>
    raise Exception(f"第{i+1}次任务失败!")
Exception: 第2次任务失败!

第2次任务失败!
为第3次任务初始化浏览器环境。
Traceback (most recent call last):
  File "d:\vs_code_projects\test2\d.py", line 20, in <module>
    env.setup() # 假设每次执行任务前都要初始化环境
  File "d:\vs_code_projects\test2\d.py", line 10, in setup
    self.playwright = self.context_manager.__enter__()
  File "D:\Anaconda\lib\site-packages\playwright\sync_api\_context_manager.py", line 48, in __enter__
    raise Error(
playwright._impl._errors.Error: It looks like you are using Playwright Sync API inside the asyncio loop.
Please use the Async API instead.

可以看到,第二次任务失败,没有顺利关闭原浏览器上下文,在后续的任务中,所有初始化行为都相当于又新增浏览器上下文,使用串行接口就会报错。
解决方法也很简单,在异常处理里关掉浏览器接口:

except Exception as e:
        import traceback
        print(traceback.format_exc())
        print(e)
        # 在下面添加即可
        print(f"在第{i+1}次任务出先异常,关闭浏览器环境。")
        env.close()

修改完后再运行这个demo,会输出:

为第1次任务初始化浏览器环境。
执行第1次任务中...
第1次任务执行成功!
关闭浏览器环境。

为第2次任务初始化浏览器环境。
执行第2次任务中...
Traceback (most recent call last):
  File "d:\vs_code_projects\test2\d.py", line 28, in <module>
    raise Exception(f"第{i+1}次任务失败!")
Exception: 第2次任务失败!

第2次任务失败!
在第2次任务出先异常,关闭浏览器环境。
为第3次任务初始化浏览器环境。
执行第3次任务中...
关闭浏览器环境。

即使有任务失败,在异常处理中妥善处理浏览器上下文,也不会出现开始的报错!

总结

微软的仓库里也有关于这个报错的一些issue,但是和我遇到的问题不一样。归根结底是这个项目(webarena)的异常处理没有弄好,有时间给它提个issue罢。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值