在 web 应用中经常会遇到 frame 嵌套页面的应用,页 WebDriver 每次只能在一个页面上识别元素,对
于 frame 嵌套内的页面上的元素,直接定位是定位是定位不到的。这个时候就需要通过 switch_to_frame()
方法将当前定位的主体切换了 frame 里。
frame.html
<html>
<head>
<script type="text/javascript">$(document).ready(function(){
});
</script>
</head>
<body>
<div class="row-fluid">
<div class="span10 well">
<h3>frame</h3>
<iframe id="if" name="nf" src="http://www.baidu.com" width="800"
height="300">
</iframe>
</div>
</div>
</body>
<script
frame.html 中的<iframe>标签,然后再定位百度输入框。
frame.py
#coding=utf-8
from selenium import webdriver
import time
import os
driver = webdriver.Firefox()
driver.get(file_path)
#切换到 iframe(id = "if")
driver.switch_to_frame("if")
#下面就可以正常的操作元素了
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
time.sleep(3)
driver.quit()
switch_to_frame() 默认可以直接取表单的 id 或 name 属性进行切换。如
frame.py
……
#id = "if"
driver.switch_to_frame("if")
#name = "nf"
driver.switch_to_frame("nf")
……
那么如果 iframe 没有可用的 id 和 name 可以通过下面的方式进行定位:
frame.py
……
#先通过 xpth 定位到 iframe
xf = driver.find_element_by_xpath('//*[@class="if"]')
#再将定位对象传给 switch_to_frame()方法
driver.switch_to_frame(xf)
……
driver.switch_to_default_content()
如果完成了在当前表单上的操作可以通过 switch_to_default_content()方法返回到上一层表单。该方法不用指定某个表单的返回,默认对应与它最近的 switch_to_frame()方法。
4.10 多窗口切换
有时候需要在不同的窗口切换,从而操作不同的窗口上的元素。在 selenium1.0 中这个问题比较难处理。
但 WebDriver 提供了 switch_to_window()方法可以切换到任意的窗口。
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.implicitly_wait(10)
#获得百度搜索窗口句柄
sreach_windows= driver.current_window_handle
driver.find_element_by_link_text(u'登录').click()
driver.find_element_by_link_text(u"立即注册").click()
#获得当前所有打开的窗口的句柄
all_handles = driver.window_handles
#进入注册窗口
for handle in all_handles:
if handle != sreach_windows:
driver.switch_to_window(handle)
print 'now register window!'
driver.find_element_by_name("account").send_keys('username')
driver.find_element_by_name('password').send_keys('password')
#……
#进入搜索窗口
for handle in all_handles:
if handle == sreach_windows:
driver.switch_to_window(handle)
print 'now sreach window!'
driver.find_element_by_id('TANGRAM__PSP_2__closeBtn').click()
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
time.sleep(5)
driver.quit()
整个脚本的处理过程:首先打开百度首页,通过 current_window_handle 获得当前窗口的句柄,并给变
量 sreach_handle。接着打开登录弹窗,在登录窗口上点击“立即注册”从而打开新的注册窗口。通过
window_handles 获得当前打开的所窗口的句柄,赋值给变量 all_handles。
第一个循环遍历 all_handles,如果 handle 不等于 sreach_handle,那么一定是注册窗口,因为脚本执行
只打开的两个窗口。所以,通过 switch_to_window()切换到注册页进行注册操作。第二个循环类似,不过
这一次判断如果 handle 等于 sreach_handle,那么切换到百度搜索页,关闭之前打开的登录弹窗,然后时行
搜索操作。
在本例中所有用到的新方法:
current_window_handle 获得当前窗口句柄
window_handles 返回的所有窗口的句柄到当前会话
switch_to_window()
用于切换到相应的窗口,与上一节的 switch_to_frame() 是类似,前者用于不同窗口的切换,后者用于
不同表单之间的切换。