1.简介

原估计宏哥这里就不对 iframe 这个知识点做介绍和讲解了,因为前边的窗口切换就为这种网页处理提供了思路,另一个原因就是虽然 iframe 很强大,但是现在很少有网站用它了。但是还是有小伙伴或者童鞋们私下问这个问题,那么宏哥就单独写一篇关于 iframe 网页处理的文章。iframe 是 web 自动化里面一个比较头疼的测试场景,在 Selenium 中处理 iframe 需要切换来切换去非常麻烦。但是在 playwright 中,让其变得非常简单,我们在使用中无需切换 iframe,直接定位元素即可。

2.iframe 是什么

iframe 就是我们常用的 iframe 标签:<iframe>。iframe 标签是框架的一种形式,也比较常用到,iframe 一般用来包含别的页面,例如我们可以在我们自己的网站页面加载别人网站或者本站其他页面的内容。iframe 标签的最大作用就是让页面变得美观。iframe 标签的用法有很多,主要区别在于对 iframe 标签定义的形式不同,例如定义 iframe 的长宽高。简单的一句话概括就是:iframe 就是 HTML 中,用于网页嵌套网页的。 一个网页可以嵌套到另一个网页中,可以嵌套很多层。和俄罗斯套娃差不多吧。

3.iframe 语法

page.frame_locator()

locator = page.frame_locator("frame").get_by_text("登录")

说明:使用 frame_locator() 定位到 iframe 上,再在上面使用 locator 方法定位元素。

可以使用 page.frame_locator() 或 locator.frame_locator() 方法创建 FrameLocator 捕获足该 iframe 中检索和定位元素。

使用示例一:

locator = page.frame_locator("my-frame").get_by_text("Submit")
locator.click()

使用 frame_locator() 定位到 iframe 上,然后继续在上面使用 locator 方法定位元素

iframe 定位器是严格的。这意味着如果有多个元素与给定的选择器匹配,则对 iframe 定位器的所有操作都会抛出异常。

# Throws if there are several frames in DOM:
page.frame_locator('.result-frame').get_by_role('button').click()

# Works because we explicitly tell locator to pick the first frame:
page.frame_locator('.result-frame').first.get_by_role('button').click()

以下代码段在带有 id 的 iframe 中定位带有文本 “提交” 的元素 my-frame,例如

locator = frame.frame_locator("#my-iframe").get_by_text("提交")
locator.click()

4.frame 定位

匹配第一个

frame_locator().first

匹配最后一个

frame_locator().last

使用 index 索引

frame_locator().nth(index)

获取全部 iframes

page.frames

5.iframe() 定位

根据 name 属性和 url 属性匹配

frame = page.frame(name="frame-name")
frame = page.frame(url=r".domain.")
frame.fill('#username-input', 'John')

6.page.frame 和 page.frame_locator 区别

page.frame_locator() 返回的对象需要用 locator() 方法定位元素,再操作元素
page.frame() 返回的对象可直接使用 fill() 、 click() 方法。

7.项目实战

网上找了半天也没有找到这样的例子,以前百度、163 的邮箱是这种。最近几年技术升级了,已经不是这种了。不找了索性宏哥自己在本地做一个这样的小 demo 给小伙伴或者童鞋们来演示一下。

7.1 被测的 HTML 代码

1.准备测试练习 index.html,如下:

<!DOCTYPE html>
<html>
<head>
    <title>北京-宏哥|iframeTestDemo</title>
    <style type="text/css">

        .button1 {
            background-color: #f44336; 
            border: none;
            color: white;
            padding: 15px 32px;
            text-align: center;
            text-decoration: none;
            display: inline-block;
            font-size: 28px;
            margin-bottom: 100px;
            text-decoration:none;
            color: white;
        }
        #myAnchor
        {
          text-decoration:none;
          color: white;
        }
    </style>
</head>
<body style="text-align:center">
<div id="wrapper" style="position: relative;top: 100px;left:0px;">
    <button class="button1"><a id="myAnchor" href="https://image.baidu.com/search/down?url=https://www.cnblogs.com/du-hong/">北京-宏哥</a></button></br>
    <div id="id1">I am a index page's div!</div>
    <input type="text" id="maininput" />
    <br/>
    <iframe id="frameA" frameborder="0" scrolling="no" style="left:857px;position:absolute;" src="iframe.html"></iframe>
</div>
</body>
</html>

2.准备测试练习 iframe.html,如下:

<!DOCTYPE html>
<html>
<head>
    <title>I am a iframe!</title>
</head>
<body>
    <div id="div1">I am iframes div!</div>
    <input id="iframeinput"></input>
</body>
</html>

3.页面效果,如下图所示:

8.牛刀小试

8.1 代码设计

8.2 参考代码

# coding=utf-8🔥

# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行

# 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2023-07-23
@author: 北京-宏哥   QQ交流群:705269076
公众号:北京宏哥
Project: 《最新出炉》系列初窥篇-Python+Playwright自动化测试-11-playwright操作iframe
'''

# 3.导入模块
from playwright.sync_api import Playwright, sync_playwright

def run(playwright: Playwright) -> None:

    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context()
    page = context.new_page()
    page.goto("C:/Users/DELL/Desktop/test/iframe/index.html")
    page.wait_for_timeout(2000)
    # 操作非 iframe上的元素
    page.locator('[id="maininput"]').fill("I am a index page's div!")
    # 操作 iframe 上的元素
    frame = page.frame_locator("iframe[id^=frameA]")
    # xpath 匹配
    frame.locator('[id="iframeinput"]').fill('This is a iframe input!')
    page.wait_for_timeout(3000)
    # page.pause()
    context.close()
    browser.close()

with sync_playwright() as playwright:
    run(playwright)

8.3 运行代码

1.运行代码,右键 Run'Test',控制台输出,如下图所示:

2.运行代码后电脑端的浏览器的动作。如下图所示:

9.小结

好了,时间不早了,今天就分享到这里,下一篇宏哥找一个还有 iframe 的在线网页给小伙伴或者童鞋们实战演示一下。


↙↙↙阅读原文可查看相关链接,并与作者交流