引入(目的):了解Html中框架的概念,掌握使用WebDriver 对象的 switch_to 属性进行框架转换,方便在selenium中定位到框架中的元素进行操作。同时,明确窗口句柄的定义,掌握应用带有窗口句柄参数的switch_to 属性,够实现窗口间的跳转。

实验内容:

一个浏览器文档窗口中一般只能显示一个网页文件,但是,使用框架标签就可以将一个浏览器文档窗口分割成多个子窗口,每个子窗口中都可以显示一个独立的网页文件。

框架元素非常的特殊,是由英文Frame翻译过来的,代表浏览器文档窗口中的一个子窗口。在html语法中,frame 元素或者 iframe元素的内部会包含一个被嵌入的另一份html文档。

每个框架都含有可以链接到其他多个网页的超链接条目,访问者单击这些超链接条目后,可以将超链接指向的网页文件显示在另一个指定的框架中。如果要求在单个应用窗口中显示一个以上的网页,就可以使用Frame(或iFrame)框架。iframe用来定义一个内联框架,在html文档里嵌入另一个html文档。iframe包含的内容和页面是一个整体,但是frame包含的内容是一个独立的区域。

在使用selenium打开一个网页时,我们的操作范围默认是当前的 html ,并不包含被嵌入的html文档里面的内容。如果我们要操作被嵌入的 html 文档 中的元素, 就必须把操作范围切换到被嵌入的文档中。

我们这里使用 WebDriver对象的switch_to属性转换,形如:

driver.switch_to.frame(frame_reference)

其中frame_reference可以是frame元素的name或者 ID属性及 frame 所对应的 WebElement 对象。

具体方法:

  • 根据frame元素的id进行切换:

例如frame元素的 id 为‘frame1’,切换语句为:

driver.switch_to.frame('frame1')
  • 根据frame元素的name属性值进行切换:

例如frame元素的name属性值为‘innerFrame’ ,切换语句为:

driver.switch_to.frame('innerFrame')
  • 根据frame元素所对应的 WebElement 对象进行切换:

例如frame元素所对应的 WebElement 对象标签名是iframe,切换语句为:

driver.switch_to.frame(driver.find_element(By.TAG_NAME, 'iframe')
  • 将WebDriver 对象切换回默认区域:
driver.switch_to.default_content()

 练习基于白月黑羽的自动化学习网站:frame切换/窗口切换 | 白月黑羽

练习1:登录 https://cdn2.byhy.net/files/selenium/sample2.html,①切换进入iframe框架,在其中选择所有动物类型并输出动物名称,②切换回外层默认部分,点击“外部按钮”,③输出网页中新出现的“你点击了外部按钮”文本信息。关闭浏览器。

具体代码如下:

import time
from selenium import webdriver
from selenium.webdriver.common.by import By# 导入驱动 括号里可填驱动的具体路径
driver = webdriver.Chrome()
# 练习一
# 打开网页
driver.get("https://cdn2.byhy.net/files/selenium/sample2.html")
#  进入内嵌Frame
driver.switch_to.frame('innerFrame')
elements = driver.find_elements(By.CLASS_NAME, 'animal')
# 循环输出元素
for element in elements:print(element.text)
#  再次返回到默认区域
driver.switch_to.default_content()driver.find_element(By.ID, 'outerbutton').click()show = driver.find_element(By.ID, 'add')
show1 = show.find_element(By.TAG_NAME, 'li')
print(show1.text)
# 关闭页面
driver.quit()

窗口切换:

引入:在针对网站的实际操作中,经常会点击一个链接或者按钮,在新窗口里面打开一个新网址,并操控新窗口里面的元素。用Selenium写的自动化程序,也要模拟实际操作,不能只在当前页面中执行,需要从 WebDriver对象对应的老窗口,切换到要进行自动化操作的新窗口中,转换语法为:driver.switch_to.window(handle),其中参数handle传入的是指定窗口的句柄。

具体方法:

WebDriver对象有window_handles 属性,这是一个列表对象,里面包括了当前浏览器里面所有的窗口句柄(相当于对应网页窗口的一个ID)。我们可以使用一个循环,依次获取 driver.window_handles 里面的所有句柄对象,并且调用 driver.switch_to.window(handle) 方法,切入到每个窗口中。然后根据 标题栏 之类的属性值判断是否为想要切换到的窗口。

从跳转后的新窗口,返回原窗口的简便方法是:开始处在原窗口时,保存原窗口句柄,在要切换回来时,仍然使用Webdriver对象的switch_to属性的 window方法,把原窗口句柄作为参数进行传递即可。

例如:

# mainWindow变量保存当前窗口的句柄
mainWindow = driver.current_window_handlefor handle in driver.window_handles: # 先切换到一个窗口 driver.switch_to.window(handle) # 得到该窗口的标题栏字符串,判断是不是我们要操作的那个窗口 if '百度一下,你就知道' in driver.title: # 如果是,那么这时候WebDriver对象就是对应的窗口,正好,跳出循环, Break…………  # 省略要在选定窗口中执行的操作# 通过前面保存的原窗口句柄,切换回原窗口
driver.switch_to.window(mainWindow)

练习2:在练习1主要操作过程和关闭浏览器操作之间,添加以下操控步骤:①登录 https://cdn2.byhy.net/files/selenium/sample3.html,②输出当前窗口的标题栏文本,点击打开新窗口的链接,③切换到新窗口并输出新窗口的标题栏文本,返回原窗口,点击“功能按钮”,输出网页中新出现的“你点击了外部按钮”。

具体代码如下:

import time
from selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
# 练习一
driver.get("https://cdn2.byhy.net/files/selenium/sample2.html")# frame1 =driver.switch_to.frame(driver.find_element(By.CSS_SELECTOR ,'.frame1'))
driver.switch_to.frame('innerFrame')
elements = driver.find_elements(By.CLASS_NAME, 'animal')for element in elements:print(element.text)driver.switch_to.default_content()driver.find_element(By.ID, 'outerbutton').click()show = driver.find_element(By.ID, 'add')
show1 = show.find_element(By.TAG_NAME, 'li')
print(show1.text)
# driver.quit()
time.sleep(2)
# 练习二
driver.get('https://cdn2.byhy.net/files/selenium/sample3.html')
mainWindow = driver.current_window_handle
print(driver.title)link = driver.find_element(By.TAG_NAME, 'a').click()
# driver.switch_to.window()
time.sleep(2)
for handle in driver.window_handles:# 先切换到该窗口driver.switch_to.window(handle)# 得到该窗口的标题栏字符串,判断是不是我们要操作的那个窗口if 'Bing' in driver.title:# 如果是,那么这时候WebDriver对象就是对应的该该窗口,正好,跳出循环,break
print(driver.title)driver.switch_to.window(mainWindow)
driver.find_element(By.ID, 'outerbutton').click()
show2 = driver.find_element(By.ID, 'add')
show3 = show2.find_element(By.TAG_NAME, 'li')
print(show3.text)
driver.quit()

练习3:以管理员身份登录 http://127.0.0.1:8047/mgr/sign.html,用户名 :byhy 密码: 88888888。点击页脚处 链接 白月黑羽教学使用,点击访问官网;然后在新打开的 白月黑羽教学网页,获取页眉导航菜单中所有教程类目(可以调用webdriver对象的maximize_window()方法最大化窗口,以便显示所有菜单 );随后再回到 白月SMS系统网页,点击退出登录。预期结果为:成功登录后,完成上述操作,验证导航菜单名,依次为:Python基础、Python进阶、Qt图形界面、Django、自动化测试、性能测试、HTML/CSS、JS语言、JS Web。验证回到登录界面(可以根据webdriver对象的current_url属性判断是否进入登录页面)。

具体代码如下:

from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By# 创建 WebDriver 实例对象,指明使用chrome浏览器驱动
wd = webdriver.Chrome()
# WebDriver 实例对象的get方法 可以让浏览器打开指定网址
wd.get('http://127.0.0.1:8047/mgr/sign.html')
# 设置最大等待时长为 10秒
wd.implicitly_wait(10)
#最大化窗口
wd.maximize_window()
#登录白月黑羽系统
elementuser = wd.find_element(By.ID,'username')
elementuser.send_keys('byhy')
elementpass = wd.find_element(By.ID, 'password')
elementpass.send_keys('88888888')
elementbutton=wd.find_element(By.TAG_NAME, 'button')
elementbutton.click()
#点击外链之前先保存本页面句柄
mainwindow=wd.current_window_handle
#点击外链
wd.find_element(By.CSS_SELECTOR ,'.pull-right>[href="http://www.python3.vip"]').click()
#寻找所选外链
for handle in wd.window_handles:wd.switch_to.window(handle)if '白月黑羽教Python' in wd.title:break
wd.maximize_window()
barelements=wd.find_elements(By.CSS_SELECTOR, 'li.nav-item span')
for barelement in barelements:print(barelement.text)
wd.switch_to.window(mainwindow)
wd.find_element(By.CSS_SELECTOR, 'span.hidden-xs').click()
wd.find_element(By.CSS_SELECTOR, '.pull-right a.btn').click()
sleep(2)
if wd.current_url=="http://127.0.0.1/mgr/sign.html":print("成功退出登录")

附加练习4:打开网易云音乐https://music.163.com/网站,点击“排行榜”,在左侧菜单栏中点击“新歌榜”,在歌曲列表中找出排名上升最多和下降最多的歌曲名称及歌手,输出格式为:

排名上升最多:歌曲名:XXX   歌手:YYY(若有上升位次相同的换行列出)

排名下降最多:歌曲名:XXX   歌手:YYY(若有下降位次相同的换行列出)

具体代码如下:

#xml是XML和HTML的解析器,其主要功能是解析和提取XML和HTML中的数据
from lxml import etree
from selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.get('https://music.163.com/')
# 隐式等待 等待页面加载成功
driver.implicitly_wait(3)
# 点击排行榜
rank_btn = driver.find_element(By.CSS_SELECTOR,"body ul >li+li>a")
rank_btn.click()
#iframe标签定位
driver.switch_to.frame('g_iframe')
#点击新歌榜
new_song_btn = driver.find_element(By.CSS_SELECTOR,".f-cb > li+li").click()
page_text = driver.execute_script("return document.documentElement.outerHTML")
#获取页面
html = etree.HTML(page_text)
up_rank_list =[]
down_rank_list =[]
up_song_name_list=[]
up_artist_list =[]
down_song_name_list=[]
down_artist_list=[]
#获取每个列表
song_rows = html.xpath('//tbody/tr')
#获取每个列表里的元素并添加到数组
for row in song_rows:up_rank = row.xpath('.//span[@class="ico u-icn u-icn-73 s-fc9"]/text()')down_rank = row.xpath('.//span[@class="ico u-icn u-icn-74 s-fc10"]/text()')song_name = row.xpath(".//b/@title")span = row.xpath(".//td[@class=' s-fc3']/span[@class='u-dur ']/text()")artist = row.xpath(".//div[@class='text']/span/@title")if up_rank != []:str1 = ''.join(up_rank)up_rank_list.append(int(str1))   # 最大上升数组song_name_str = ''.join(song_name)up_song_name_list.append(song_name_str)artist_str =''.join(artist)up_artist_list.append(artist_str)if down_rank !=[]:str2 = ''.join(down_rank)down_rank_list.append(int(str2)) # 最大下降数组song_name_str = ''.join(song_name)down_song_name_list.append(song_name_str)artist_str =''.join(artist)down_artist_list.append(artist_str)
t1 = max(up_rank_list)
num = len(up_rank_list)
n=0
for i in up_rank_list:if i ==t1:n=n+1
if n!=1:for j in range(num):if up_rank_list[j] == t1:print("排名上升最多:"+up_song_name_list[j]+" \t 歌手:"+up_artist_list[j])
else:a1 = up_rank_list.index(t1)print("排名上升最多:"+up_song_name_list[a1]+" \t 歌手:"+up_artist_list[a1])t2 = max(down_rank_list)
num2 = len(down_rank_list)
# print(num)
n1=0
for i1 in down_rank_list:if i1 ==t1:n1=n1+1
if n1!=1:for j1 in range(num2):if down_rank_list[j1] == t2:print("排名下降最多:"+down_song_name_list[j1]+" \t 歌手:"+down_artist_list[j1])
else:a2 = down_rank_list.index(t2)print("排名下降最多:"+down_song_name_list[a2]+" \t 歌手:"+down_artist_list[a2])
# 退出页面
driver.quit()

当然方法不是唯一的,奈何水平有限,还是在不断学习中,希望共同进步,与君共勉呀!

********************************************分隔符***********************************************

在此针对练习4再添加两个不同的解决方法:

方法一:

driver = webdriver.Chrome()
driver.get('https://music.163.com/')
driver.find_element(By.CSS_SELECTOR, "#g_nav2 li:nth-child(2) a").click()
driver.switch_to.frame(driver.find_element(By.ID, 'g_iframe'))
driver.find_element(By.CSS_SELECTOR, '#toplist li:nth-child(2) a').click()
item = driver.find_element(By.CSS_SELECTOR, '#song-list-pre-cache table tbody')
up_table =[]
lown_table =[]
num=0
sleep(1)
for i in item.find_elements(By.TAG_NAME, 'tr'):ranking = i.find_element(By.CSS_SELECTOR, '.rk span')name = i.find_element(By.CSS_SELECTOR, 'td:nth-child(2) .ttc a b')singer = i.find_element(By.CSS_SELECTOR, 'td:nth-child(4) div')class_list = ranking.get_attribute('class').split(" ")temp=[(ranking.text),name.get_attribute('title'),singer.get_attribute('title')]if 'u-icn-73' in class_list:up_table.append(temp)elif 'u-icn-74' in class_list:lown_table.append(temp)
up_table.sort(key=lambda x:int(x[0]), reverse=True)
lown_table.sort(key=lambda x:int(x[0]), reverse=True)
for table in [up_table, lown_table]:for i in table:if i[0] == table[0][0]:print(f"排名{['上升','下降'][num]}最多: 歌曲名:{i[1]} 歌手:{i[2]}")else:breaknum +=1

方法二:

driver = webdriver.Chrome()
driver.get('https://music.163.com/')
driver.find_element(By.CSS_SELECTOR,'[href="/discover/toplist"]').click()
driver.switch_to.frame('contentFrame')
driver.find_element(By.CSS_SELECTOR, '[href="/discover/toplist?id=3779629"]').click()
maxnum=[]
minnum=[]
count1 =[]
count2=[]
count =0
list_all = driver.find_elements(By.CSS_SELECTOR, '.rk>span')
for n in list_all:count = count+1txt = n.get_attribute("className").split(" ")[-1]if txt == "s-fc9":maxnum.append(int(n.text))count1.append(count)elif txt == "s-fc10":minnum.append(int(n.text))count2.append(count)print(max(maxnum))
print(max(minnum))upnum = []
for i in range(len(maxnum)):if maxnum[i]== max(maxnum):upnum.append(count1[i])
# downnum用来记录下降最快的位于所有列表的哪个位置
downnum = []
for j in range(len(minnum)):if minnum[j] == max(minnum):downnum.append(count2[j])
songname = driver.find_elements(By.CSS_SELECTOR, '.ttc>.txt>a>b')
singer = driver.find_elements(By.CSS_SELECTOR, '.text>span')
for m in upnum:print("排名上升最多∶歌曲名: "+songname[m-1].get_attribute("title")+"歌手:"+singer[m-1].get_attribute("title"))
for n in downnum:print("排名下降最多∶歌曲名:"+songname[n-1].get_attribute("title")+"歌手: "+singer[n-1].get_attribute("title"))

Frame及窗口切换相关推荐

  1. frame切换、多窗口切换

    目标 1. 掌握切换frame的方法 2. 掌握多窗口切换的技巧 frame切换 frame:HTML页面中的一种框架,主要作用是在当前页面中指定区域显示另一页面元素:形式一:[了解] <fra ...

  2. 自动化测试——多窗口切换和切换frame

    这里写目录标题 一.多窗口切换 1.base.py:公共代码 2.切换句柄的方式1,通过for循环 3.切换句柄的方式2,通过索引切换 4.源代码 二.frame窗口 1.什么是frame? 2.Fr ...

  3. web自动化之frame、文件上传、窗口切换、悬浮菜单

    #frame切换 driver.switch_to.frame(driver.find_element('name','iframe1')) driver.find_element('id', 'kw ...

  4. 4.下拉选择框,弹出框。滚动条,(frame切换、多窗口切换,很重要,常用)等等,面试重要

    文章目录 target 下拉选择框 弹出框-- driver.switch_to.alert 滚动条 frame切换-- 重要 多窗口切换 截屏 验证码 cookie target 下拉选择框--se ...

  5. Web自动化测试Selenium(4)frame切换/窗口切换/选择框-2021-10-09

    1. frame切换 1.1 问题描述 选择 class 属性值为 plant 的元素. elements = wb.find_element_by_css_selector('.plant') 表示 ...

  6. Selenium3 + Python3自动化测试系列——多窗口切换

    多窗口切换 在页面操作过程中有时候点击某个链接会弹出新的窗口,这时就需要主机切换到新打开的窗口上进行操作. WebDriver提供了switch_to.window()方法,可以实现在不同的窗口之间切 ...

  7. Python+Selenium学习笔记8 - 多表单多窗口切换

    1.多表单切换 下图为待测页面:内嵌百度首页 切换到百度首页进行操作 1 #coding = utf-8 2 3 from selenium importwebdriver4 importos5 im ...

  8. python3 + selenium 之窗口切换

    窗口切换 此代码来源学习后对淘宝操作实践记录: 以下代码在Chrome61和IE11上正常运行,Firefox5.7上运行存在一些问题须改进,应该是火狐不兼容差link_text部分和循环经常报错,在 ...

  9. web页面:窗口切换

    1.标签页切换 在某个窗口上点击某个链接在新标签页显示新窗口时,如果想要点击新标签页的元素时,需要进行窗口切换. driver.switch_to.window('窗口名称') from seleni ...

最新文章

  1. Yii2.0 模态弹出框+ajax提交表单
  2. laravel5.6 数组传递到前端
  3. 无线路由器发起ARP攻击,致使网络中断,这是为什么?
  4. cwntos新建目录挂载磁盘_详解Linux磁盘挂载、分区、扩容操作的实现方法
  5. 龙蜥利器:系统运维工具 SysAK的云上应用性能诊断 | 龙蜥技术
  6. java 树的数据结构_Java数据结构之树(二叉树)
  7. 【clickhouse】yandex 官方 BalancedClickhouseDataSource 源码分析
  8. Maven创建的Web项目无法使用EL表达式
  9. 我的开源项目:TS封装格式分析器
  10. vscode还用装git_使用vscode实现git同步
  11. PDM系统的结构设计
  12. 一款牛逼的Android端身份证合成工具
  13. 51单片机c语言音乐盒设计,基于51单片机的音乐盒课程设计开题报告精品
  14. error: undefined reference to __write_chk错误
  15. HTC M7日文版HTL22刷机包 毒蛇2.5.0 ART NFC Sense6.0
  16. ubuntu 安装 hustoj
  17. Java POI 设置字体下划线、方框打勾、字体加粗
  18. ssh连接报错“WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED“问题原因及解决方法
  19. js实现点击上一题和下一题出现对应的题目,
  20. OS-机械硬盘的磁盘初始化

热门文章

  1. 普朗克黑体辐射公式使用指南
  2. 【TTF字体】TTF字体结构
  3. ubuntuv20启动界面美化_KWGT插件,手机主题美化教程,附最全插件合集!
  4. 计算机小白对计算机的认识
  5. 衡量批处理计算机系统的性能指标,操作系统概念.doc
  6. c++ 以逗号或者其他符号分割中英文字符串和数字型字符串
  7. python后端知识点的自我复习
  8. Android 点击无效问题总结
  9. Cocos Creator Spine动画产生位移时,动画位置获取问题 (root的使用)
  10. 新品上线 | 企企通推出达人管理系统,助力达人营销提效增速