• Selenium 6


    本文作者官网 白月黑羽教Python


    点击这里,边看视频讲解,边学习以下内容

    切换到frame


    点击这里,边看视频讲解,边学习以下内容

    请大家点击这里,打开这个链接

    如果我们要 选择 下图方框中 所有的 蔬菜,使用css选择,怎么写表达式?

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

    白月黑羽Python3教程

    大家可能会照旧写出如下代码:

    from selenium import webdriver
    
    wd = webdriver.Chrome(r'd:webdriverschromedriver.exe')
    
    wd.get('http://cdn1.python3.vip/files/selenium/sample2.html')
    
    # 根据 class name 选择元素,返回的是 一个列表
    elements = wd.find_elements_by_class_name('plant')
    
    for element in elements:
        print(element.text)
    

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

    为什么呢?

    因为仔细看,你可以发现, 这些元素是在一个叫 iframe的 元素中的。

    白月黑羽Python3教程

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

    在我们使用selenium打开一个网页是, 我们的操作范围 缺省是当前的 html , 并不包含被嵌入的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'd:webdriverschromedriver.exe')
    
    wd.get('http://cdn1.python3.vip/files/selenium/sample2.html')
    
    
    # 先根据name属性值 'innerFrame',切换到iframe中
    wd.switch_to.frame('innerFrame')
    
    # 根据 class name 选择元素,返回的是 一个列表
    elements = wd.find_elements_by_class_name('plant')
    
    for element in elements:
        print(element.text)
    


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

    这时候,如果我们又需要操作 主html(我们把最外部的html称之为主html) 里面的元素了呢?

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

    很简单,写如下代码即可

    wd.switch_to.default_content()
    

    例如,在上面 代码 操作完 frame里面的元素后, 需要 点击 主html 里面的按钮,就可以这样写

    from selenium import webdriver
    
    wd = webdriver.Chrome(r'd:webdriverschromedriver.exe')
    
    wd.get('http://cdn1.python3.vip/files/selenium/sample2.html')
    
    
    # 先根据name属性值 'innerFrame',切换到iframe中
    wd.switch_to.frame('innerFrame')
    
    # 根据 class name 选择元素,返回的是 一个列表
    elements = wd.find_elements_by_class_name('plant')
    
    for element in elements:
        print(element.text)
    
    # 切换回 最外部的 HTML 中
    wd.switch_to.default_content()
    
    # 然后再 选择操作 外部的 HTML 中 的元素
    wd.find_element_by_id('outerbutton').click()
    
    wd.quit()
    
    

    切换到新的窗口


    点击这里,边看视频讲解,边学习以下内容

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

    请大家点击这里,打开这个链接

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

    如果我们用Selenium写自动化程序 在新窗口里面 打开一个新网址, 并且去自动化操作新窗口里面的元素,会有什么问题呢?

    问题就在于,即使新窗口打开了, 这时候,我们的 WebDriver对象对应的 还是老窗口,自动化操作也还是在老窗口进行,

    我们可以运行如下代码验证一下

    from selenium import webdriver
    
    
    wd = webdriver.Chrome(r'd:webdriverschromedriver.exe')
    wd.implicitly_wait(10)
    
    wd.get('http://cdn1.python3.vip/files/selenium/sample3.html')
    
    # 点击打开新窗口的链接
    link = wd.find_element_by_tag_name("a")
    link.click()
    
    # wd.title属性是当前窗口的标题栏 文本
    print(wd.title)
    
    

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

    白月黑羽测试网页3
    

    说明, 我们的 WebDriver对象指向的还是老窗口,否则的话,运行结果就应该新窗口的标题栏 "微软Bing搜索"



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

    可以使用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) 方法,切入到每个窗口,

    然后检查里面该窗口对象的属性(可以是标题栏,地址栏),判断是不是我们要操作的那个窗口,如果是,就跳出循环。


    同样的,如果我们在新窗口 操作结束后, 还要回到原来的窗口,该怎么办?

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

    还有更省事的方法。

    因为我们一开始就在 原来的窗口里面,我们知道 进入新窗口操作完后,还要回来,可以事先 保存该老窗口的 句柄,使用如下方法

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

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

    #通过前面保存的老窗口的句柄,自己切换到老窗口
    wd.switch_to.window(mainWindow)
    
  • 相关阅读:
    windows下python访问ipv6报错
    windows下python的包管理器pip安装
    python添加windows域验证
    Java系列笔记(1)
    JVM调优总结 -Xms -Xmx -Xmn -Xss
    5种调优Java NIO和NIO.2的方式
    Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收
    jmap,jhat分析内存
    JVM 垃圾回收算法
    JVM 类加载过程
  • 原文地址:https://www.cnblogs.com/baiyueheiyu/p/12851354.html
Copyright © 2020-2023  润新知