元素定位是UI自动化核心内容,与传统的selenium相比,最大的区别在于selenium是协议的单向的,只负责做而不等待响应,因此需要结合强制等待,隐式等待和显示等待来判定,playwright则有自动等待机制,即做的时候还要等待响应,例如点击操作时,会判定元素是否可点击交互
selenium
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
element = driver.find_element(By.ID, 'su')
element.click() # 正常执行
driver.refresh() # 刷新页面后执行
time.sleep(3)
element.click() # 执行报错
通过find_element()方法获取的元素进行第一次点击时,正常执行,刷新页面后再次点击报错,因为dom元素重新加载,element是之前的dom元素对象。
playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
context = browser.new_context()
page = context.new_page()
page.goto('https://www.baidu.com/')
element = page.locator('#su')
element.click() # 正常执行
page.reload()
element.click() # 正常执行
locator()方法返回的是一个定位器对象,跟selenium不同之处在于,这是动态的,在click()动作执行时才会真正的查找该对象,属于懒查询(需要真正使用时才查询元素)
元素定位
locator()就是playwright核心的定位方法,参数有以下5个:
selector :接受xpath或css_selector定位元素的字符串参数
has: 接受一个locator对象,表示匹配selector中包含有该locator的元素
has_not:接受一个locator对象,表示匹配selector中不包含有该locator的元素
has_text: 表示匹配指定文本元素,文本在该节点或其后代节点中
has_not_text: 表示不匹配指定文本元素,文本在该节点或其后代节点中
has_text和has_not_text还可以接受正则匹配对象
以如下的html为例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="test">
<h2>测试文本</h2>
</div>
<div class="test">
<span>测试123</span>
</div>
</body>
</html>
使用has和has_not的方法
# 后代节点包含h2,高亮对应的测试文本
page.locator('div', has=page.locator('h2')).highlight()
page.wait_for_timeout(2000)
# 后代节点不包含h2,高亮对象的测试123
page.locator('div', has_not=page.locator('h2')).highlight()
page.wait_for_timeout(2000)
结果如下图:
使用has_text和has_not_text方法
# 正则匹配包含"测试+至少一个数字"
page.locator('div', has_text=re.compile(r'测试\d+')).highlight()
page.wait_for_timeout(2000)
# 不包含文本测试123,匹配"测试文本"
page.locator('div', has_not_text='测试123').highlight()
page.wait_for_timeout(2000)
执行结果如图: