Playwright 是微软在 2020 年初开源的新一代自动化测试工具,添加了默认等待时间增加脚本稳定性,并提供视频录制、网络请求支持、自定义的定位器、自带调试器等新特性。
Installation | Playwright Python
安装
分两步,第一步安装库,第二步安装包内需要的浏览器框架
# 第一步,安装playwright的python版本
pip install playwright
# 第二步,安装playwright自带的浏览器和ffmepg,此步骤耗时较长
playwright install
# 或者python -m playwright install
录制功能
录制功能可能是playwright最神奇的功能之一,在命令行输入以下指令后,系统会开启一个浏览器与程序画板,在浏览器上的操作可以实时映射到代码上,最后只需要复制生成的Code然后稍微修改一下就可以直接当脚本用了!
# -o 定义代码输出的文件
# -b 定义使用的浏览器
playwright codegen -o script.py -b firefox
Basic Structure
playwright支持两种浏览器自动化模式,同步模式和异步模式,以下的代码基本按照异步模式来。
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
context = browser.new_context()
page = context.new_page()
page.goto(URL)
browser
browser = playwright.chromium.launch(headless=False)
浏览器:支持多种浏览器:Chromium(chrome、edge)、Firefox、WebKit(Safari),一般每一种浏览器只需要创建一个browser实例。通过控制headless参数来判断是否启用实体浏览器。
context
context1 = browser.new_context()
上下文:一个浏览器实例下可以有多个context,将浏览器分割成不同的上下文,以实现会话的分离,如需要不同用户登录同一个网页,不需要创建多个浏览器实例,只需要创建多个context即可。
另外,还可以指定各种参数来控制诸多参数,比如下例更改了浏览器的定位,定位到了故宫。
context = browser.new_context(
locale='zh-CN',
geolocation={'longitude': 116.39014, 'latitude': 39.913904},
permissions=['geolocation'])
page
页面:一个context下可以有多个page,一个page就代表一个浏览器的标签页或弹出窗口,用于进行页面操作。示例:
page = context.new_page()
# 显式导航,类似于在浏览器中输入URL
page.goto('http://example.com')
# 在输入框中输入字符
page.fill('#search', 'query')
# 点击提交按钮
page.click('#submit')
# 打印当前url
print(page.url)
处理新窗口
在网页进行模拟指令的时候,常常会要处理新弹出的窗口(称之为popup),在page类中需要进行额外的操作才能转向那个新的标签页。
官方文档:Pages | Playwright Python
# 这是一般的处理方法
# Get popup after a specific action (e.g., click)
with page.expect_popup() as popup_info:
page.get_by_text("open the popup").click()
popup = popup_info.value
popup.wait_for_load_state()
print(popup.title())
如果并不清楚界面什么时候会有新窗口
# 这种方法会让目标page产生新窗口的时候(监听到‘popup’事件时),都会自动调用handle_popup函数
# Get all popups when they open
def handle_popup(popup):
popup.wait_for_load_state()
print(popup.title())
page.on("popup", handle_popup)
定位器(Locator)
所有元素操作都需要使用选择器定位到要操作的元素,playwright同时支持css、xpath和自定义的选择器,使用时无需指定类型,playwright会自动进行判断。示例:
# 使用css选择器
page.locator("css=button").click()
page.locator("button").click()
# 使用xpath选择器
page.locator("xpath=//button").click()
page.locator("//button").click()
特殊定位器
如果需要使用更多特殊功能的定位器,那么请看:Other Locators | Playwright Python
# 匹配有文字"All products"的所有文章元素,切记可能匹配多个,届时需要使用filter
page.locator('article:has-text("All products")')
# 精确匹配显示文字为Log的元素
page.locator(':text-is("Log")')
定位器后处理
获取了定位器之后,可能会对该定位器进行各种加工才能获得目标元素,而playwright支持对定位器进行再次加工。
# 获取文字为"专题:"元素的父元素
page.locator(':text-is("专题:")').locator('..')
# 获取所有列表元素,并选中其中有orange字符的
page.get_by_role("listitem").filter(has_text="orange")
# 获取可视的button元素
page.locator("button").locator("visible=true").click()
自动等待
# Playwright 会等待 #search 元素出现在 DOM 中
page.fill('#search', 'query')
# Playwright 会等待元素停止动画并接受点击
page.click('#search')
# 等待 #search 出现在 DOM 中
page.wait_for_selector('#search', state='attached')
# 等待 #promo 可见, 例如具有 `visibility:visible`
page.wait_for_selector('#promo')
# 等待 #details 变得不可见, 例如通过 `display:none`.
page.wait_for_selector('#details', state='hidden')
# 等待 #promo 从 DOM 中移除
page.wait_for_selector('#promo', state='detached')
获取数据
定位器有许多类方法,能够获取网页中需要的信息
example_xpath = '//html/body/div'
# 下面的两种方法均可以获得元素内的html代码
page.locator(example_xpath).inner_html()
page.locator(example_xpath).element_handle().inner_html()
# inner_html改为inner_text就可以获取元素内的文本
page.locator(example_xpath).inner_text()
元素处理器(ElementHandle)
locator和elementHandle的区别
-
locator保存的是元素捕获的逻辑。
-
elementHandle指向特定的元素。
举个例子,如果一个elementHandle所指向的元素的文本或者属性发生改变,那么elementHandle仍然指向原来那个没有改变的元素,而locator每一个都会根据捕获的逻辑去获取最新的那个元素,也就是改变后的元素。
Example
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
for browser_type in [p.chromium, p.firefox, p.webkit]:
browser = browser_type.launch(headless=False)
page = browser.new_page()
page.goto('https://www.baidu.com')
page.screenshot(path=f'screenshot-{browser_type.name}.png')
print(page.title())
browser.close()
[文章导入自 http://qzq-go.notion.site/7e7ff51b7dc14db4bf2e3ed45895aa0d 访问原文获取高清图片]