一、概述
playwright是微软开源的用于web测试和自动化的框架。可以同时支持chromium、firefox、webkit,并且可以支持多种开发语言,包括python、c#、java等。
# playwright可以支持的系统:linux、windows、macOS
二、安装配置
# python语言为例
2.1 install
python版本要求>3.6
# pip install playwright
# 这个命令会安装所支持的浏览器
# playwright install
2.2 示例
playwright支持同步和异步的方式,但是原理基本一致,演示的代码以同步的方式为例
2.2.1 第一个脚本
p.chromium.launch是初始化谷歌浏览器,这里当然可以换成p.firefox.launch()浏览器的选择以自己的需求为准,或者是同时使用多个浏览器测试。
浏览器初始化参数说明:
- headless: 是否启动浏览器界面,False为启动,方便调试,True为不启动。
- proxy: http代理如果需要访问的url无法直接访问可以配置相关的代理进行。
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False, proxy={"server": "http://127.0.0.1:10809"})
page = browser.new_page()
page.goto("https://www.baidu.com", timeout=0)
print(page.title())
browser.close()
2.2.2 选择器selector
selector就是根据html文档中根据条件筛选特定的内容。playwright支持文本选择器、CSS、Xpath、Vue等选择器。
1、xpath选择器
使用chromium快速获取腾讯云登录账号密码输入框的位置:
打开腾讯云登录窗口,F12打开开发者模式选中使用选中输入窗口:
右键选中输入框所在资源,选择copy-->xpath,即可获取到登录窗口的位置。
使用playwright登录腾讯云平台示例,使用xpath selector是需要指定"xpath=XPATH"
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
borwser = p.chromium.launch(headless=False)
page = borwser.new_page()
page.goto("https://cloud.tencent.com/login", timeout=0)
# wait_for_selector等待指定资源出现
page.wait_for_selector('xpath=//*[@id="loginBox"]/div/div/div[4]/div[2]/div[1]/a/span', state="visible")
page.click('xpath=//*[@id="loginBox"]/div/div/div[4]/div[2]/div[1]/a/span')
page.wait_for_selector('xpath=//*[@id="loginBox"]/div/div/div[2]/div[2]/ul/li[1]/div/div/input')
# fill可以在指定位置输入文本内容。
page.fill('xpath=//*[@id="loginBox"]/div/div/div[2]/div[2]/ul/li[1]/div/div/input', "username")
page.fill('xpath=//*[@id="loginBox"]/div/div/div[2]/div[2]/ul/li[2]/div/div/input', "password")
# click是鼠标事件,默认是鼠标左键单击。可以通过button指定["left", "middle", "right"]
page.click('xpath=//*[@id="loginBox"]/div/div/div[2]/div[2]/div[2]/a[1]')
2、css选择器
右键选中输入框所在资源,选择copy-->copy selector,即可获取到登录窗口的位置。
使用playwright css选择器登录腾讯云平台示例,
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
borwser = p.chromium.launch(headless=False)
page = borwser.new_page()
page.goto("https://cloud.tencent.com/login", timeout=0)
page.wait_for_selector('#loginBox > div > div > div.clg-other-mod.J-otherMod > div.clg-other-con.J-switchLoginTypeArea > div:nth-child(1) > a > span', state="visible")
page.click('#loginBox > div > div > div.clg-other-mod.J-otherMod > div.clg-other-con.J-switchLoginTypeArea > div:nth-child(1) > a > span')
page.wait_for_selector('#loginBox > div > div > div.clg-mod-tab.J-loginContentBox.J-qcloginBox > div.clg-form.J-loginForm > ul > li:nth-child(1) > div > div > input')
page.fill('#loginBox > div > div > div.clg-mod-tab.J-loginContentBox.J-qcloginBox > div.clg-form.J-loginForm > ul > li:nth-child(1) > div > div > input', "username")
page.fill('#loginBox > div > div > div.clg-mod-tab.J-loginContentBox.J-qcloginBox > div.clg-form.J-loginForm > ul > li:nth-child(2) > div > div > input', "PASSWORD")
page.click('#loginBox > div > div > div.clg-mod-tab.J-loginContentBox.J-qcloginBox > div.clg-form.J-loginForm > div.clg-form-btn > a.clg-btn.J-loginBtn',)
2.3 frame问题
如果页面上frame标签,如果使用selector选择frame内的标签,是无法直接选中,playwright提供了frame_locator进行切换;示例如下:
page.wait_for_selector("#gsft_main", state="attached")
sub_page = page.frame_locator("#gsft_main")
sub_page可以操作当前frame下的html文档,选中table获取内容。
sub_page.locator("#task_table > tbody").inner_text()
如果不利用上述方法可以使用css选择的方式,'#gsft_main >> control=enter-frame',#gsft_main是frame的id,后面使用正常的css选择的语法即可。
page.locator("#gsft_main >> control=enter-frame >> #row_task_1 > td:nth-child(3) > a")
2.4 获取资源数量
获取页面行数据/列数据是,需要进行遍历,为了确定遍历的次数,可以首先获取行/列的数量,以腾讯云待续费资源为例,到期续费的产品7天/15天数量是不一致,不同的账号也是不同的,如果需要爬取列表我们获取产品类别的数量。
通过开发者模式查看产品类别为5个button,即获取到这个button数量即可。
代码示例,selector定位到button这一层,但是不能指定是第几个,然后使用count方法可以统计这一层的button数量。
source_count = page.locator('xpath=//*[@id="account-renewal"]/main/div/div[2]/div/div[2]/div/div/div/div[2]/div/button').count()
2.5 单击链接是"_blank"类型的
在页面操作点击如果是_blank属性的会打开新的浏览器标签页,如果要操作打开后的页面需要定位新的浏览器标签页。 我们以腾讯云站内信为例,点击之后会打开新的标签页。
# context.expect_page()方法当前浏览器上下文中等待创建新的页面。
with page.context.expect_page() as new_page_info:
for num in range(1, page.locator('xpath=//*[@id="message_list"]/div[2]/a').count() + 1):
# 点击站内信的打开新的页面,把new_page_info页面的值赋值给新的变量就可以进行对新的页面进行操作。
page.click('xpath=//*[@id="message_list"]/div[2]/a[{}]'.format(num))
new_page = new_page_info.value
new_page.wait_for_load_state()
new_page.screenshot(path="image_{}.png".format(num))
2.6 录制脚本
playwright支持脚本录制,录制完成会自动生成代码。
# -b指定浏览器,--target指定语言,不指定域名默认打开空白页,再输入域名可以
playwright codegen --target python -b chromium https://www.xxx.com