Selenium(六):frame切换、窗口切换

1. 切换到frame

index.html:css

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>    
    </head>
    <script>

        
    function appendEle(info) {
        var node = document.createElement("LI");
        var textnode = document.createTextNode(info);
        node.appendChild(textnode);
        document.getElementById("add").appendChild(node);
    }

    function clickbutton() {       
        appendEle("你点击了外部按钮");
    }

    </script>
    <body>
        <div><button id='outerbutton' onclick='clickbutton()' >外部按钮</button></div>

        <br>

        <div class="baiyueheiyu"><span>下面的内容是iframe中的</span></div>

        <iframe src="sample1.html" id='frame1' name='innerFrame' width="300" height="200"></iframe>
        <div id="add"></div>
    </body>
</html>

sample1.html:html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            .wolf{
                color: red;
            }
        </style>
    </head>
    <body>
        <div class="raise"><span>喜羊羊</span></div>
        <div class="raise"><span>美羊羊</span></div>
        <div class="raise"><span>暖羊羊</span></div>
 
        <div class="wolf"><span>灰太狼</span></div>
        <div class="wolf"><span>红太狼</span></div>
        <div class="wolf"><span>小灰灰</span></div>
    </body>
</html>

若是咱们要选择下图方框中全部的羊,使用css选择,怎么写表达式?node

固然,要先查看到它们的html元素特征web

 

你们可能会照旧写出以下代码: chrome

from selenium import webdriver

wd = webdriver.Chrome(r'E:\webdrivers\chromedriver.exe')

wd.get('http://127.0.0.1:8020/day01/index.html')

# 根据class name选择元素,返回的是一个列表
elements = wd.find_elements_by_class_name('raise')

for element in elements:
    print(element.text)

运行一下,你就会发现,运行结果打印内容为空白,说明没有选择到class属性值为raise的元素。浏览器

为何呢?app

由于仔细看,你能够发现,这些元素是在一个叫iframe的元素中的。测试

这个iframe元素很是的特殊,在html语法中,frame元素或者iframe元素的内部,会包含一个被嵌入的另外一份html文档。 网站

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

1.1 从主html切换到被嵌入的文档

若是咱们要操做被嵌入的html文档中的元素,就必须切换操做范围到被嵌入的文档中。

怎么切换呢?

使用WebDriver对象的switch_to属性,像这样:

wd.switch_to.frame(frame_reference)

其中,frame_reference能够是frame元素的属性name或者ID。

好比这里,就能够填写iframe元素的id‘frame1’或者name属性值‘innerFrame’。

像这样

wd.switch_to.frame('frame1')

或者

wd.switch_to.frame('innerFrame')

也能够填写frame 所对应的 WebElement 对象。

咱们能够根据frame的元素位置或者属性特性,使用find系列的方法,选择到该元素,获得对应的WebElement对象。

好比,这里就能够写:

wd.switch_to.frame(wd.find_element_by_tag_name("iframe"))

而后,就能够进行后续操做frame里面的元素了。

上面的例子的正确代码以下:

from selenium import webdriver

wd = webdriver.Chrome(r'E:\webdrivers\chromedriver.exe')

wd.get('http://127.0.0.1:8020/day01/index.html')


# 先根据name属性值 'innerFrame',切换到iframe中
wd.switch_to.frame('innerFrame')

# 根据 class name 选择元素,返回的是 一个列表
elements = wd.find_elements_by_class_name('raise')

for element in elements:
    print(element.text)

1.2 从被嵌入的文档切换到主html

若是咱们已经切换到某个iframe里面进行操做了,那么后续选择和操做界面元素就都是在这个frame里面进行的。

这时候,若是咱们又须要操做主html(咱们把最外部的html称之为主html)里面的元素了呢?

怎么切换回原来的主html呢?

很简单,写以下代码便可:

wd.switch_to.default_content()

例如,在上面代码操做完frame里面的元素后,须要点击主html里面的按钮,就能够这样写:

from selenium import webdriver

wd = webdriver.Chrome(r'E:\webdrivers\chromedriver.exe')

wd.get('http://127.0.0.1:8020/day01/index.html')


# 先根据name属性值 'innerFrame',切换到iframe中
wd.switch_to.frame('innerFrame')

# 根据 class name 选择元素,返回的是 一个列表
elements = wd.find_elements_by_class_name('raise')

for element in elements:
    print(element.text)

# 切换回 最外部的 HTML 中
wd.switch_to.default_content()

# 而后再 选择操做 外部的 HTML 中 的元素
wd.find_element_by_id('outerbutton').click()

2. 切换窗口

在网页上操做的时候,咱们常常遇到,点击一个连接或者按钮,就会打开一个新窗口。

html代码:

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <title>主html</title>
    </head>
    <script>
            function appendEle(info) {
                var node = document.createElement("LI");
                var textnode = document.createTextNode(info);
                node.appendChild(textnode);
                document.getElementById("add").appendChild(node);
            }
        
            function clickbutton() {       
                appendEle("你点击了外部按钮");
            }
        
    </script>
    <body>
        <a href="http://www.bing.com" target="_blank">访问bing网站</a>
        
        <div><button id='outerbutton' onclick='clickbutton()' >功能按钮</button></div>

        <br>

        <div id="add"></div>

    </body>
</html>

在打开的网页中,点击 连接 “访问bing网站” , 就会弹出一个新窗口,访问bing网址。

若是咱们用Selenium写自动化程序在新窗口里面打开一个新网址,而且去自动化操做新窗口里面的元素,会有什么问题呢?

问题就在于,即便新窗口打开了,这时候,咱们的 WebDriver对象对应的仍是老窗口,自动化操做也仍是在老窗口进行,咱们能够运行以下代码验证一下:

from selenium import webdriver

wd = webdriver.Chrome(r'E:\webdrivers\chromedriver.exe')
wd.implicitly_wait(10)

wd.get('http://127.0.0.1:8020/day01/index.html')

# 点击打开新窗口的连接
link = wd.find_element_by_tag_name("a")
link.click()

# wd.title属性是当前窗口的标题栏 文本
print(wd.title)

运行完程序后,最后一行打印当前窗口的标题栏文本,输出内容是:

主html

说明,咱们的 WebDriver对象指向的仍是老窗口,不然的话,运行结果就应该新窗口的标题栏“微软Bing搜索”。

2.1 切换到新窗口

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

可使用Webdriver对象的switch_to属性的window方法,以下所示:

wd.switch_to.window(handle)

其中,参数handle须要传入什么呢?

WebDriver对象有window_handles属性,这是一个列表对象,里面包括了当前浏览器里面全部的窗口句柄。

所谓句柄,你们能够想象成对应网页窗口的一个ID,那么咱们就能够经过 相似下面的代码:

for handle in wd.window_handles:
    # 先切换到该窗口
    wd.switch_to.window(handle)
    # 获得该窗口的标题栏字符串,判断是否是咱们要操做的那个窗口
    if 'Bing' in wd.title:
        # 若是是,那么这时候WebDriver对象就是对应的该该窗口,正好,跳出循环,
        break

上面代码的用意就是:

咱们依次获取wd.window_handles里面的全部 句柄 对象,而且调用wd.switch_to.window(handle)方法,切入到每一个窗口,而后检查里面该窗口对象的属性(能够是标题栏,地址栏),判断是否是咱们要操做的那个窗口,若是是,就跳出循环。

完整代码:

from selenium import webdriver

wd = webdriver.Chrome(r'E:\webdrivers\chromedriver.exe')
wd.implicitly_wait(10)

wd.get('http://127.0.0.1:8020/day01/index.html')

# 点击打开新窗口的连接
link = wd.find_element_by_tag_name("a")
link.click()

for handle in wd.window_handles:
    # 先切换到该窗口
    wd.switch_to.window(handle)
    # 获得该窗口的标题栏字符串,判断是否是咱们要操做的那个窗口
    if 'Bing' in wd.title:
        # 若是是,那么这时候WebDriver对象就是对应的该该窗口,正好,跳出循环,
        break

# wd.title属性是当前窗口的标题栏 文本
print(wd.title)

2.2 切换回原来的窗口

一样的,若是咱们在新窗口 操做结束后,还要回到原来的窗口,该怎么办?

咱们能够仍然使用上面的方法,依次切入窗口,而后根据标题栏之类的属性值判断。

还有更省事的方法。

由于咱们一开始就在原来的窗口里面,咱们知道进入新窗口操做完后,还要回来,能够事先保存该老窗口的句柄,使用以下方法:

# mainWindow变量保存当前窗口的句柄
mainWindow = wd.current_window_handle

切换到新窗口操做完后,就能够直接像下面这样,将driver对应的对象返回到原来的窗口。

#经过前面保存的老窗口的句柄,本身切换到老窗口
wd.switch_to.window(mainWindow)

完整代码:

from selenium import webdriver

wd = webdriver.Chrome(r'E:\webdrivers\chromedriver.exe')
wd.implicitly_wait(10)

wd.get('http://127.0.0.1:8020/day01/index.html')

# mainWindow变量保存当前窗口的句柄
mainWindow = wd.current_window_handle

# wd.title属性是当前窗口的标题栏 文本
print(wd.title)

# 点击打开新窗口的连接
link = wd.find_element_by_tag_name("a")
link.click()

for handle in wd.window_handles:
    # 先切换到该窗口
    wd.switch_to.window(handle)
    # 获得该窗口的标题栏字符串,判断是否是咱们要操做的那个窗口
    if 'Bing' in wd.title:
        # 若是是,那么这时候WebDriver对象就是对应的该该窗口,正好,跳出循环,
        break

# wd.title属性是当前窗口的标题栏 文本
print(wd.title)

#经过前面保存的老窗口的句柄,本身切换到老窗口
wd.switch_to.window(mainWindow)

# wd.title属性是当前窗口的标题栏 文本
print(wd.title)

结果:

主html
微软 Bing 搜索 - 国内版
主html

经过测试的结果,咱们能够看到窗口切换了两次。

相关文章
相关标签/搜索