51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1335|回复: 1
打印 上一主题 下一主题

[转贴] Selenium如何使用句柄方式切换窗口?

[复制链接]
  • TA的每日心情
    擦汗
    2 小时前
  • 签到天数: 1026 天

    连续签到: 1 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2022-3-7 11:06:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    窗口切换
      我们在使用打开链接时,通常会存在2种情况:
      1. 在当前窗口打开,即覆盖。
      2. 新建窗口打开,保留原有窗口。
      示例:
      ·百度首页搜索:博客园。
      · 打开博客园官网,获取当前页精华帖的标题。
      · 回到百度输入框,并打印出 title。

      代码如下:
      from selenium import webdriver
      driver = webdriver.Chrome()
      driver.implicitly_wait(10)
      # 打开百度首页
      driver.get('http://baidu.com')
      # 输入 博客园 并点击 回车
      driver.find_element_by_id('kw').send_keys('博客园\n')
      # 找到博客园的官网,并点击;点击后会在新的窗口打开链接
      driver.find_element_by_xpath("//h3//a[contains(.,'官网')]/../a[1]").click()
      # 打印当前窗口的 title
      print(driver.title)
      # 打印当前窗口的 url
      print(driver.current_url)
      # 点击博客园的 精华 贴
      driver.find_element_by_css_selector('a[title="编辑精选博文"]').click()
      ......



      输出结果如下:
      博客园_百度搜索
      https://www.baidu.com/s?ie=utf-8 ... 48&rsv_sug4=348
      selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"a[title="编辑精选博文"]"}
      # 报错信息,未定位到该元素



      浏览器实现结果


    通过浏览器的实现结果,和代码的运行结果,可以判断出:即使web页面已跳转至新窗口,但是代码逻辑还在原有窗口。
    为解决该问题,我们需要引入 句柄 的概念:窗口句柄 ,粗略的理解,每个窗口对应一个句柄,句柄可认为是一个唯一长字符串。

      获取句柄的方法:
      · 获取当前页面句柄:driver.current_window_handle
      · 获取所有页面句柄:driver.window_handles
      通过句柄,我们可以进行窗口的切换。
      · 切换窗口:driver.switch_to.window()

      示例:
      from selenium import webdriver
      driver = webdriver.Chrome()
      driver.implicitly_wait(10)
      # 打开百度首页
      driver.get('http://baidu.com')
      # 输入 博客园 并点击 回车
      driver.find_element_by_id('kw').send_keys('博客园\n')
      # 找到博客园的官网,并点击;点击后会在新的窗口打开链接
      driver.find_element_by_xpath("//h3//a[contains(.,'官网')]/../a[1]").click()
      # 打印出所有的句柄信息
      print(driver.window_handles)
      driver.quit()



      输出结果如下:
      ['CDwindow-998407BA3D6B34956871D337B6F377FE', 'CDwindow-844FF13AAEE0E14487AD368DEAA7A0AE']
      # 从结果中我们可以看出:
      # driver.window_handles的数据类型是一个 列表



      让我们回到上面的需求:此时我们唯一要做的就是,打开新的窗口后,代码切换至新窗口,并输出结果。
      from selenium import webdriver
      driver = webdriver.Chrome()
      driver.implicitly_wait(10)
      # 打开百度首页
      driver.get('http://baidu.com')
      # 输入 博客园 并点击 回车
      driver.find_element_by_id('kw').send_keys('博客园\n')
      # 找到博客园的官网,并点击;点击后会在新的窗口打开链接
      driver.find_element_by_xpath("//h3//a[contains(.,'官网')]/../a[1]").click()
      # 打印当前窗口的 title
      print('切换前的title:',driver.title)
      # 切换至新窗口
      # 首先,我们要先获取到一个主句柄,作为灯塔,防止"迷路"
      mainWindow = driver.current_window_handle
      # 接着我们要获取所有的句柄信息,并赋值给 handles
      handles = driver.window_handles
      # 使用for循环,遍历所有的handles,以便判断
      for handle in handles:
          # 使用driver.switch_to.window()方法,切入句柄所在的窗口
          driver.switch_to.window(handle)
          # 判断 "代码" 是否在当前窗口的title中,如果在,跳出循环
          if "代码" in driver.title:
              break
      # 让我们打印一下当前窗口的 title
      print('切换后的title:',driver.title)
      # 点击博客园的 精华 贴
      driver.find_element_by_css_selector('a[title="编辑精选博文"]').click()
      # 定位到标题的元素,并赋值给 items
      items = driver.find_elements_by_css_selector('div[class="post_item"] h3>a')
      for one in items:
          print(one.text)
      # 打印完成后,切回主窗口,并打印出当前窗口的 title
      driver.switch_to.window(mainWindow)
      print('切回主句柄的title:',driver.title)



      输出结果如下:
      切换前的title: 博客园_百度搜索
      切换后的title: 博客园 - 代码改变世界
      ------------------2021-5-30 前20的精华帖-----------------------------
      【面试】如果你这样回答“什么是线程安全”,面试官都会对你刮目相看
      【面试】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好[url=]文章[/url](快快珍藏)
      为啥程序会有[url=]bug[/url]
      关于分布式锁原理的一些学习与思考-redis分布式锁,zookeeper分布式锁
      ERP不规范,同事两行泪
      只有程序员才能读懂的西游记
      从软件工程的角度解读任正非的新年公开信
      通俗易懂,C#如何安全、高效地玩转任何种类的内存之Span的本质(一)。
      分布式系统关注点——99%的人都能看懂的「熔断」以及最佳实践
      神经网络的基本工作原理
      哎呀,我老大写Bug啦——记一次MessageQueue的优化
      机器学习web服务化实战:一次吐血的服务化之路
      Windbg分析高内存占用问题
      我是怎么把一个项目带崩的
      彼之蜜糖,吾之砒霜——聊聊软件开发中的最佳实践
      Linux的内存分页管理
      通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?
      藏在正则表达式里的陷阱
      你所不知道的日志异步落库
      为什么说 Java 程序员到了必须掌握 Spring Boot 的时候?

      切回主句柄的title:博客园_百度搜索



    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

  • TA的每日心情
    郁闷
    2022-4-23 21:35
  • 签到天数: 45 天

    连续签到: 3 天

    [LV.5]测试团长

    2#
    发表于 2022-3-22 20:29:26 | 只看该作者
    每一步都写得详细,点赞
    回复 支持 反对

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-9-29 11:24 , Processed in 0.104961 second(s), 23 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表