Frame及窗口切换

Frame及窗口切换

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

实验要求:在pycharm 环境下完成实验目的中所述各项任务

实验条件:win7/10、pycharm、selenium4.4.0

实验内容及步骤:

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

框架元素非常的特殊,是由英文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()

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

五、 窗口切换

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

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

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# mainWindow变量保存当前窗口的句柄 

mainWindow = driver.current_window_handle


for handle in driver.window_handles:

# 先切换到一个窗口

driver.switch_to.window(handle)

# 得到该窗口的标题栏字符串,判断是不是我们要操作的那个窗口

if '百度一下,你就知道' in driver.title:

# 如果是,那么这时候WebDriver对象就是对应的窗口,正好,跳出循环,

Break
………… # 省略要在选定窗口中执行的操作

# 通过前面保存的原窗口句柄,切换回原窗口
driver.switch_to.window(mainWindow)

练习1:登录 https://cdn2.byhy.net/files/selenium/sample2.html,

①切换进入iframe框架,在其中选择所有动物类型并输出动物名称,

②切换回外层默认部分,点击“外部按钮”,

③输出网页中新出现的“你点击了外部按钮”文本信息。关闭浏览器

练习2:在练习1主要操作过程和关闭浏览器操作之间,添加以下操控步骤:

①登录 https://cdn2.byhy.net/files/selenium/sample3.html,

②输出当前窗口的标题栏文本,点击打开新窗口的链接,

③切换到新窗口并输出新窗口的标题栏文本,

④返回原窗口,点击“功能按钮”,输出网页中新出现的“你点击了外部按钮”。

  1. 完成练习1和练习2并提交代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    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")

    # 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()

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

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

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

提交代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#xml是XML和HTML的解析器,其主要功能是解析和提取XML和HTML中的数据
from lxml import etree
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By


# 方法一
# driver = 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 = 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:
# break
# num +=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+1
# txt = 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"))
#


  1. 以管理员身份登录 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属性判断是否进入登录页面)。

提交代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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("成功退出登录")


Frame及窗口切换
http://example.com/2025/01/07/测试笔记/selenium/selenium05/
作者
Helios
发布于
2025年1月7日
许可协议