selenium多表单之间切换

1、多表单(或者说框架)切换

  什么是表单:就是网页标签名为frame或iframe 的元素,表单引用了其他页面的链接,真正的页面数据没有出现在源码中,但是 在浏览器中可以看见,与浏览器的多个窗口类似

  为什么需要切换:在web应用会遇到frame/iframe表单嵌套的应用,selenium的WebDriver只能在一个页面对元素操作及定位,对表单里的元素无法直接定位,此时需要切换到表单页面再进行定位

  表单切换方法1:switch_to.frame('id的值'),此方法是默认取表单的id的值或name属性的值进行定位(现在163邮箱没有name属性,id的是动态id,无法使用此方法进行切换表单)

  表单切换方法2:先定位到表单,再切换到表单,然后才能正常定位到表单内的元素

# 导包
from selenium import webdriver
import time
# 创建一个浏览器对象
driver = webdriver.Chrome()
# 默认浏览器全屏
driver.maximize_window()
# 访问163邮箱
url = 'https://email.163.com/'
driver.get(url)

# 不切换表单,直接定位到输入框
try:
    driver.find_element_by_css_selector('#auto-id-1596976820406')
    print('不需要切换表单可以直接定位')
except:
    print('定位失败,请切换表单')

# 第一种方式切换表单
# 格式:driver.switch_to.frame('id的值或name属性的值')
# driver.switch_to.frame('auto-id-1596976820406')# 此网址id为动态id,无法用此方法定位
# 第二种方式(先定位到表单,再切换到表单,然后才能正常定位到表单里的输入框)
# 定位到表单frame
fr = driver.find_element_by_tag_name('iframe')
# 切换到表单
driver.switch_to.frame(fr)
# 定位账号输入框并输入
usr_email = driver.find_element_by_name('email')
usr_email.send_keys('8888888888')
time.sleep(1)
# 定位到密码输入框并输入
password = driver.find_element_by_name('password')
password.send_keys('00000000')
time.sleep(3)
# 定位登录按钮
log = driver.find_element_by_id('dologin')
log.click()
# 获取图片
time.sleep(2)
driver.get_screenshot_as_file('获取表单登录图片.png')

# 关闭浏览器
driver.quit()

2、多层表单切换(本地文件网页)

  跳到最外层页面:driver.switch_to.default_content()

  跳到上一级页面:driver.switch_to.parent_frame()

# 导入WebDriver和os模块(用于获取本地连接)
from selenium import webdriver
import os

# 创建一个浏览器默认最大化
driver = webdriver.Firefox()
driver.maximize_window()

# os.path.abspath()方法是获取本地路径(此处是本地网页路径)
bendi_path = 'file:///' + os.path.abspath('./day4/example_frame.html')
print(bendi_path)
# 访问本地路径网页
driver.get(bendi_path)

# 此网页有三层,默认电脑光标在第一层,此时需要定位到最内层的百度,需要经过两次frame表单
# 因为默认的是在第一层,所有此时先切换到第二层
driver.switch_to.frame('kw_frame1')
# 再切换到最内层
driver.switch_to.frame('kw_frame2')
# 此时已经进入最内层,可以正常开始定位
# 定位百度搜索框并输入
sr = driver.find_element_by_id('kw')
sr.send_keys('兵法')

# 跳出到最外层
driver.switch_to.default_content()
# 验证跳出最外层
try:
    # 按理此时不在最内层,无法定位最内层的搜索框
    driver.find_element_by_id('kw')
    print('还在最内层,可以定位到')
except:
    print('已经跳出最内层')

# 跳回上一层,执行两次,跳到最内层
driver.switch_to.parent_frame()
driver.switch_to.parent_frame()
# 验证是否跳回上一层
try:
    driver.find_element_by_id('kw')
    print('已经跳回上一层')
except:
    print('跳转两次后回到了最内层')

# 关闭浏览器
driver.quit()

 

代码中两个简单的网页源码,把下面源码保存成HTML格式,放于与脚本同一级目录即可使用

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>inner</title>
</head>
<body>
<div class="row-fluid">
<div class="span6 well">
<h3>inner</h3>
<iframe id="kw_frame2" src="https://www.baidu.com/" width="700"
height="500"></iframe>
<a href="javascript:alert('watir-webdriver better than
selenium webdriver;')">click</a>
</div>
</div>
</body>
</html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>frame</title>
<script type="text/javascript" async=""
src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
"></script>
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" />
<script type="text/javascript">
$(document).ready(function(){
});
</script>
</head>
<body>
<div class="row-fluid">
<div class="span10 well">
<h3>frame</h3>
<iframe id="kw_frame1" src="inner.html" width="800",
height="600"></iframe>
</div>
</div>
</body>
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
</html>

 

posted @ 2020-08-09 23:40  吾言!  阅读(973)  评论(0编辑  收藏  举报