Playwright自动化框架

一、Playwright简介

微软开发,基于Chrome 开发者工具协议(Chrome DevTools Protocol,简称CDP)的浏览器自动化工具。

优点:

  • 不需要浏览器驱动
  • 速度比较快、天生支持异步
  • 几乎可以自动化浏览器的全部功能
  • 定位比较方便
  • 很好和AI结合(MCP、SKILL高级支持)

缺点:

  • 支持浏览器比较有限:主要是Chrome、Chromeium

二、安装Playwright

官网:playwright.dev/python/docs...

python 复制代码
pip install pytest-playwright
playwright install chromium  #playwright默认使用这里安装的浏览器,而不是用户自己安装的chrome

三、录制脚本

python 复制代码
playwright codegen https://www.sogou.com/

执行后会自动打开浏览器并跳转搜狗搜索的网页。搜索今日黄金价格,Playwright会将搜索操作录制成脚本。如何断言呢?可以按照下图点击完"1"后,点击"2",将"2"中的内容作为断言条件,也可以在"3"中修改断言条件,最后点"4"将断言操作记录到录制脚本中。

录制好的脚本在这个窗口:

四、Playwright对浏览器的常用操作

这部分是固定内容

python 复制代码
from playwright.sync_api import Playwright, sync_playwright, expect

def run(playwright: Playwright) -> None:
    browser = playwright.chromium.launch(headless=False)  #启动浏览器,返回 Browser 类型对象,使用有头模式
    context = browser.new_context()  #创建 BrowserContext对象
    page = context.new_page()  #创建新页面,返回 Page 类型对象
    page.goto("https://www.sogou.com/")
                            ...
    
    context.close()
    browser.close()

with sync_playwright() as playwright:
    run(playwright)

1、页面导航

python 复制代码
page.goto("https://www.sogou.com/")  #跳转url
page.reload() #刷新
page.go_back() #后退
page.go_forward() #前进

2、页面内容

python 复制代码
print("title:",page.title()) #网页标题(HTML中的title)
print("url:",page.url) #当前网页地址
print("content:",page.content()) #当前网页内容(完整HTML)

3、页面动作

python 复制代码
page.set_viewport_size({"width":1080,"height":300}) #设置窗口大小
page.mouse.wheel() #页面滚动
page.expect_dialog() #弹窗处理
page.screenshot(path="1.png") #页面截图
page.evaluate('location.href="https://qq.com"') #执行js代码
#执行js代码,从浏览器内部进行自动化,这里的操作是通过js代码跳转到腾讯网页。例如一些场景不便从外部进行自动化们可以通过js代码从浏览器内部执行一些自动化操作

4、元素内容

python 复制代码
.inner_text() 获取可见文本
.input_value() 获取输入框值
.get_attribute() 获取元素属性
.count() 获取匹配元素个数

5、元素动作

python 复制代码
.fill() 输入内容
.click() 点击
.press() 按键(Enter/Tab)
.check() 勾选复选框
.select_option() 下拉选择
.set_input_files() 文件上传

6、断言

页面断言

python 复制代码
expect(page).to_have_url() 校验 URL
expect(page).to_have_title() 校验标题

元素断言

python 复制代码
expect(locator).to_be_visible() 元素可见
expect(locator).to_contain_text() 包含文本
expect(locator).to_have_text() 文本完全匹配
expect(locator).to_have_value() 输入框值校验
expect(locator).to_be_enabled() 元素可用

五、Playwright元素定位

Selenium经典的八大元素定位,Selenium把这 8 种作为独立、平级的定位类型:id | name | class name | link name(完整链接文本) | partial link text(部分链接文本) | tag name(标签名,如 input/div) | css selector | xpath

Playwright 底层只有两大类选择器:CSS、XPath。像 id/name/class/tag,本质都属于 CSS 选择器;link 文本定位是 Playwright 内置的文本选择器语法,并不是独立底层类型。

固定内容:

python 复制代码
from playwright.sync_api import Playwright, sync_playwright, expect

def run(playwright: Playwright) -> None:
    browser = playwright.chromium.launch(headless=False)  #启动浏览器,返回 Browser 类型对象,使用有头模式
    context = browser.new_context()  #创建 BrowserContext对象
    page = context.new_page()  #创建新页面,返回 Page 类型对象
    page.goto("https://www.bilibili.com/?spm_id_from=333.1387.0.0")
    ##Playwright底层使用的是异步的python库进行各种事件处理,time.sleep 会破坏异步框架的处理逻辑。可以使用Page对象的wait_for_timeout方法达到等待效果,单位是 毫秒
    page.wait_for_timeout(1000)  # 等待1秒,确保页面加载完成
                                        ...
    
    context.close()
    browser.close()

with sync_playwright() as playwright:
    run(playwright)

1、XPATH元素定位

  • / 从根节点选取
  • // 从非根节点选取
  • * 任意节点选取
  • @ 根据属性筛选
  • text() 根据文本筛选
  • and 关联属性或者链接文本
  • \[\] 可以放置下标/属性/链接文本
  • . 选取当前节点
  • .. 选取当前节点的父节点
  • contains 包含
python 复制代码
#单一属性定位-->设置
text1 = page.locator('//span[@name="tj_settingicon"]').inner_text()
print(text1)
#多属性定位-->设置
text2 = page.locator('//span[@name="tj_settingicon" and @id="s-usersetting-top"]').inner_text()
print(text2)
#父节点定位-->设置
text3=page.locator('//div[@id="u1"]/span').inner_text()
print(text3)
python 复制代码
#通过下标定位-->新闻
text4=page.locator('//a[@class="mnav c-font-normal c-color-t"][1]').inner_text() #直接使用下标,"新闻"是1,"hao123"是2,以此类推
text4=page.locator('//div[@class="s-top-tabs"]/a[1]').inner_text()  #通过父节点+下标方式
python 复制代码
#通过.和..定位
text5=page.locator('//a[@name="tjfanyi"]/div/../../../../a').inner_text()  #通过"翻译"定位到"更多"按钮
print(text5)
python 复制代码
#通过文本定位
text6=page.locator('//a[text()="更多"]').inner_text()
print(text6)
#通过模糊匹配
text7=page.locator('//a[contains(text(), "hao")]').inner_text()
print(text7)

总结:

  • 尽量不要使用绝对路径
  • 尽量减少路径级别
  • 尽量不要使用下标
  • 尽量使用最简洁的写法

2、CSS元素定位

  • id选择器
  • class选择器
  • 元素选择器
  • 属性选择器
  • 层级选择器
python 复制代码
    #id属性定位,id=可以简写为#
    page.locator('#query').fill('id属性')
    #name属性定位,name没有简写,只能用方括号定位
    page.locator('[name="query"]').fill('name属性定位')
    #class属性定位
    page.locator('.sec-input').fill('class属性')
    #标签+属性定位
    page.locator('input#query').fill('标签+id属性定位')
    #层级关系定位
    page.locator('div>form>span>input.sec-input').fill('层级关系定位')
相关推荐
ClouGence2 小时前
GPT-6 做 UI 自动化测试:Demo 惊艳,但真的适合长期回归吗?
前端·chatgpt·测试
杀不死的坏蛋c2 小时前
Pytest自动化测试框架
测试
何宝荣1435 小时前
Postman 接口测试入门:从发请求到写断言
测试
2601_962382431 天前
3种python自动化测试框架推荐,看看哪个适合你?_robotframework和pytest
测试·自学·
围炉聊科技2 天前
Playwright Test Agents 三件套实测 ——智能体基建系列
浏览器·ai编程·测试
月読h3 天前
# Agent 的自主执行与工程决策记录:读 Anthropic 和 AWS ADR
agent·测试
囤囤囤3 天前
基于 WebUSB 与 CDP:在浏览器端实现 Android 设备通信与无证书抓包实践
测试