在介绍 selenium 的时候,宏哥也介绍过等待,是因为在某些元素出现后,才可以进行操作。有时候我们自己忘记添加等待时间后,查了半天代码确定就是没有问题,奇怪的就是获取不到元素。然后搞了好久,或者经过别人的提示才恍然大悟没有添加等待时间。而 playwright 为了避免我们犯这么 low 的错误,它对元素执行操作前,会进行一系列可操作性检查,以确保这些行动按预期运行。它会自动等待所有相关检查通过,然后才执行请求的操作。如果所需的检查未在给定的范围内通过则抛出 timeout,操作将失败并显示 TimeoutError。正是由于 playwright 添加了默认等待时间才会增加脚本稳定性。
什么是 playwright 的自动等待?在官网我们可以看到这样一段话:
Auto-wait. Playwright waits for elements to be actionable prior to performing actions. It also has a rich set of introspection events. The combination of the two eliminates the need for artificial timeouts - the primary cause of flaky tests.
翻译过来的大概意思就是说:自动等待:playwright 对元素执行操作前,会进行一系列可操作性检查,以确保这些行动按预期运行。它会自动等待所有相关检查通过,然后才执行请求的操作。如果所需的检查未在给定的范围内通过则抛出 timeout,操作将失败并显示 TimeoutError。
如元素点击操作,在操作元素之前需要预判:
以下是针对每个操作执行的可操作性检查的完整列表:
Action | Attached | Visible | Stable | Receives Events | Enabled | Editable |
---|---|---|---|---|---|---|
check | Yes | Yes | Yes | Yes | Yes | - |
click | Yes | Yes | Yes | Yes | Yes | - |
dblclick | Yes | Yes | Yes | Yes | Yes | - |
setChecked | Yes | Yes | Yes | Yes | Yes | - |
tap | Yes | Yes | Yes | Yes | Yes | - |
uncheck | Yes | Yes | Yes | Yes | Yes | - |
hover | Yes | Yes | Yes | Yes | - | - |
scrollIntoViewIfNeeded | Yes | - | Yes | - | - | - |
screenshot | Yes | Yes | Yes | - | - | - |
fill | Yes | Yes | - | - | Yes | Yes |
selectText | Yes | Yes | - | - | - | - |
dispatchEvent | Yes | - | - | - | - | - |
focus | Yes | - | - | - | - | - |
getAttribute | Yes | - | - | - | - | - |
innerText | Yes | - | - | - | - | - |
innerHTML | Yes | - | - | - | - | - |
press | Yes | - | - | - | - | - |
setInputFiles | Yes | - | - | - | - | - |
selectOption | Yes | Yes | - | - | Yes | - |
textContent | Yes | - | - | - | - | - |
type | Yes | - | - | - | - | - |
通过前边的学习和实践,想必大家和宏哥有同样的感觉吧:Playwright 打开浏览器运行脚本的速度那就是一个字:快!相对于 selenium,playwright 执行速度会更快,眨眼间就完事了。因此为了便于我们查看执行的过程,我们可以加上等待来减缓执行,但是与 selenium 不同,playwright 通过 slow_mo(单位是毫秒)减慢执行速度,它的作用范围是全局的,从启动浏览器到操作元素每个动作都会有等待间隔,方便在出现问题的时候看到页面操作情况。使用方法如下:
chromium.launch(headless=False, slow_mo=50)
宏哥就按照上边的方法实践一下,看一下是否真的可以减缓执行速度。
# coding=utf-8🔥
# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行
# 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2023-05-25
@author: 北京-宏哥 QQ交流群:705269076
公众号:北京宏哥
Project: 《《最新出炉》系列初窥篇-Python+Playwright自动化测试-4-playwright自动等待及扩展
'''
# 3.导入模块
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False, slow_mo=5000)
page = browser.new_page()
page.goto("https://image.baidu.com/search/down?url=https://www.baidu.com")
print(page.title())
page.fill('#kw', "北京-宏哥")
page.click('#su')
browser.close()
1.运行代码,右键 Run'test',控制台输出,如下图所示:
2.代码的执行过程,如下图所示:
与 selenium 不同,playwright 不再支持 time.sleep(),而是使用 page.wait_for_timeout() 来实现等待,当我们调试时需要等待,即可使用该方法。Playwright 在查找元素的时候具有自动等待功能,如果你在调试的时候需要使用等待,你应该使用 page.wait_for_timeout(5000) 代替 time.sleep(5) 并且最好不要等待超时。
注:请使用 wait( wait_for_timeout) 方法而不是 time 模块。这是因为我们内部依赖于异步操作,并且在使用时 time.sleep(5) 无法正确处理它们。
宏哥就按照上边的方法实践一下。
# coding=utf-8🔥
# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行
# 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2023-05-25
@author: 北京-宏哥 QQ交流群:705269076
公众号:北京宏哥
Project: 《《最新出炉》系列初窥篇-Python+Playwright自动化测试-4-playwright自动等待及扩展
'''
# 3.导入模块
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False, slow_mo=1000)
page = browser.new_page()
page.goto("https://image.baidu.com/search/down?url=https://www.baidu.com")
print(page.title())
# 等待5秒
page.wait_for_timeout(5000)
page.fill('#kw', "北京-宏哥")
page.click('#su')
# 等待3秒
page.wait_for_timeout(3000)
browser.close()
1.运行代码,右键 Run'test',控制台输出,如下图所示:
2.代码的执行过程,如下图所示:
本文主要介绍了一些 playwright 的使用与 selenium 有一些不同,我们需要注意不同点,比如 playwright 默认是无头模式运行以及等待的改变。下一篇文章我们将介绍 playwright 定位元素的方法。
好了,今天时间也不早了,宏哥就讲解和分享到这里,感谢您耐心的阅读,希望对您有所帮助。
即使 Playwright 已经做了充分准备,但是也并不完全稳定,在实际项目中依旧容易出现因页面加载导致事件没有生效等问题,为了避免这些问题,需要自行设置等待。
# 固定等待1秒
page.wait_for_timeout(1000)
# 等待事件
page.wait_for_event(event)
# 等待加载状态
page.get_by_role("button").click()
page.wait_for_load_state()