playwright入门

558 阅读4分钟

一、概述

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打开开发者模式选中使用选中输入窗口: image.png

右键选中输入框所在资源,选择copy-->xpath,即可获取到登录窗口的位置。 image.png

使用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,即可获取到登录窗口的位置。

image.png 使用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数量即可。 image.png

代码示例,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