【Playwright学习笔记 09】界面操作、对话框、窗口操作

0 阅读6分钟

frame切换

在html语法中, frame 元素 或者 iframe 元素的内部 会包含一个 被嵌入的 另一份html文档。

在我们使用 Playwright 打开一个网页时, 操作范围 缺省是当前的 html , 并不包含被嵌入的html文档里面的内容。

如果我们要 定位/操作 被嵌入的 html 文档 中的元素, 就必须 切换操作范围 到 被嵌入的文档中。

使用 Page 或者 Locator 对象的 frame_locator 方法定位到你要操作的frame。

这个 方法会产生一个 FrameLocator对象,后续的定位,就使用这个对象,在其内部进行定位。

像这样

# 产生一个  FrameLocator 对象
frame = page.frame_locator("iframe[src='sample1.html']")

# 再 在其内部进行定位
lcs = frame.locator('.plant').all()
for lc in lcs:
    print(lc.inner_text(timeout=1000))

其中, frame_locator 方法的参数是 css 或者 xpath selector

窗口切换

在网页上操作的时候,我们经常遇到,点击一个链接 或者 按钮,就会打开一个 新窗口

我们要到新的窗口里面操作,该怎么做呢?

这时,需要使用 BrowserContext 对象。如下

from playwright.sync_api import sync_playwright
pw = sync_playwright().start()

browser = pw.chromium.launch(headless=False)

# 创建 BrowserContext 对象
context = browser.new_context()

# 通过context 创建page
page = context.new_page() 

page.goto("https://www.byhy.net/cdn2/files/selenium/sample3.html")

# 点击链接,打开新窗口
page.locator("a").click()

# 等待2秒, 不能用 time.sleep
page.wait_for_timeout(2000)

# pages属性是 所有窗口对应Page对象的列表
newPage = context.pages[1]

# 打印新网页窗口标题
print(newPage.title())

# 打印老网页窗口标题
print(page.title())

可以通过不同的page对象操作对应的不同窗口

BrowserContext 对象有个 pages 属性,这是一个列表,里面依次为所有窗口对应Page对象。

如果自动化打开了很多链接窗口,不知道目标窗口的次序号,这时可以根据标题栏定位到要操作的page

那么我们就可以通过 类似下面的代码,

for pg in  context.pages:
    # 得到该窗口的标题栏字符串,判断是不是我们要操作的那个窗口
    if '必应' in pg.title():
        break

print(pg.title()) 

设置当前tab

如果当前界面有很多窗口,要把某个窗口作为当前活动窗口显示出来,可以调用该窗口对应的Page对象的 bring_to_front 方法。

关闭网页窗口

前面我们学过Browser对象有close 方法,那是关闭整个浏览器。

如果只是要关闭某个网页窗口,可以调用该窗口对应的Page对象的 close 方法。

冻结界面

在 开发者工具栏 console 里面执行如下js代码

setTimeout(function(){debugger}, 5000)

也可以在控制台输入debugger来冻结页面

截屏

整个网页 截屏,使用 Page 对象的 screenshot 方法。

比如

# 截屏当前页面可见内容,保存到当前工作目录下的ss1.png文件中
page.screenshot(path='ss1.png')

# 截屏 完整页面,页面内容长度超过窗口高度时,包括不可见部分。
page.screenshot(path='ss1.png', full_page=True)

也可以只对 某个元素的显示内容 进行截屏,使用 Locator 对象的 screenshot 方法。

比如

page.locator('input[type=file]').screenshot(path='ss2.png')

拖拽

要实现拖拽功能,可以使用Page对象的 drag_and_drop 方法。

比如,对下面这段 html

<span id="t1">t1</span>
<span id="t2">t2</span>


<form >
  <div id="captcha">
  </div>
  <input type="text" placeholder="captcha" />
  <button type="submit">Submit</button>
</form>

要选中 span#t1 文本内容,并且拖拽到 输入框 [placeholder="captcha"] 里面去,可以使用如下代码:

# 选中  `span#t1`  文本内容
page.locator('#t1').select_text()

# 拖拽到 输入框  `[placeholder="captcha"]` 里面去
page.drag_and_drop('#t1', '[placeholder="captcha"]')

drag_and_drop 方法的:

第1个参数是被拖动元素的 css selector 或者 xpath selector , 如果可以匹配页面多个元素,取第一个匹配到的元素

第1个参数是拖动目标元素的 css selector 或者 xpath selector, 如果可以匹配页面多个元素,取第一个匹配到的元素

如果被拖动元素的Locator对象已经产生,可以直接调用其 drag_to 方法 进行拖动

上例中,代码也可以这样写

# 选中  `span#t1`  文本内容
lc = page.locator('#t1')

lc.select_text()

# 拖拽到 输入框  `[placeholder="captcha"]` 里面去
lc.drag_to(page.locator('[placeholder="captcha"]'))

注意, drag_to 的参数是 目标元素的 Locator 对象 , 而不是 selector 表达式字符串

弹出对话框

有的时候,我们经常会在操作界面的时候,出现一些弹出的对话框。

弹出的对话框有三种类型,分别是 alert(警告信息)confirm(确认信息)prompt(提示输入)

Alert

Alert 弹出框,目的就是显示通知信息,只需用户看完信息后,点击 OK(确定) 就可以了。

那么,自动化的时候,代码怎么模拟用户点击 OK 按钮呢?

可以这样

from playwright.sync_api import sync_playwright
pw = sync_playwright().start()
browser = pw.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://www.byhy.net/cdn2/files/selenium/test4.html")

# 处理 弹出对话框 的 回调函数
def handleDlg(dialog):
    # 等待1秒
    page.wait_for_timeout(1000)
    # 点击确定
    dialog.accept()
    # 打印 弹出框 提示信息
    print(dialog.message) 

# 设置弹出对话框事件回调函数
page.on("dialog", handleDlg )

# 点击 alert 按钮
page.locator('#b1').click()

处理函数中被回调时,会传入 Dialog 对象

这个对象的

accept 方法作用等同于点击确定按钮

dismiss 方法作用等同于点击取消按钮

message 属性就是对话框界面的提示信息字符串

注意:

  • 注册的处理函数中一定要调用 accept 或者 dismiss 方法,让对话框消失。

    否则当对话框弹出时,后续任何代码都不会执行,并且会有超时错误。

  • Playwright 在界面有弹出框时,发现如果没有任何注册的处理函数,会自动点击取消

Confirm

Confirm弹出框,主要是让用户确认是否要进行某个操作。

比如:当管理员在网站上选择删除某个账号时,就可能会弹出 Confirm弹出框, 要求确认是否确定要删除。

Confirm弹出框 有两个选择供用户选择,分别是 OKCancel , 分别代表 确定取消 操作。

前面说过,处理函数中被回调时,会传入 Dialog 对象

这个对象的

accept 方法作用等同于点击确定按钮

dismiss 方法作用等同于点击取消按钮

Prompt

出现 Prompt 弹出框 是需要用户输入一些信息,提交上去。

比如:当管理员在网站上选择给某个账号延期时,就可能会弹出 Prompt 弹出框, 要求输入延期多长时间。

怎么办呢?

Dialog 对象,这个对象的 accept 方法可以输入参数字符串,作为要输入的信息

比如,前面的代码改为

from playwright.sync_api import sync_playwright
pw = sync_playwright().start()
browser = pw.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://www.byhy.net/cdn2/files/selenium/test4.html")


def handleDlg(dialog):    
    page.wait_for_timeout(1000)
    dialog.accept('你好啊') # 输入信息,并确定

page.on("dialog", handleDlg)

# 点击 confirm 按钮
page.locator('#b3').click()

input('....')