1、定位一组元素
webdriver 可以很方便的使用 findElement 方法来定位某个特定的对象,不过有时
候我们却需要定位一组对象,这时候就需要使用 findElements 方法。
定位一组对象一般用于以下场景:

  • 批量操作对象,比如将页面上所有的 checkbox 都勾上
  • 先获取一组对象,再在这组对象中过滤出需要具体定位的一些对象。比如定位出页面上所有的 checkbox,然后选择最后一个

checkbox.html

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>Checkbox</title>
<script type="text/javascript" async=""
src="https://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
src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></
script>
</head>
<body>
<h3>checkbox</h3>
<div class="well">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="c1">checkbox1</label>
<div class="controls">
<input type="checkbox" id="c1" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="c2">checkbox2</label>
<div class="controls">
<input type="checkbox" id="c2" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="c3">checkbox3</label>
<div class="controls">
<input type="checkbox" id="c3" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="r">radio</label>
<div class="controls">
<input type="radio" id="r1" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="r">radio</label>
<div class="controls">
<input type="radio" id="r2" />
</div>
</div>
</form>
</div>
</body>
</html>

将这段代码保存复制到记事本中,将保存成 checkbox.html 文件。(注意,这个页面需要和我们的自动化脚本放在同一个目录下)

通过浏览器打开,得到下列页面:

1.1 、第一种定位方法

通过浏览器打个这个页面我们看到三个复选框和两个单选框。下面我们就来定位这三个复选框。

# -*- coding: utf-8 -*-
from selenium import webdriver
import time
import os
dr = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('checkbox.html')
dr.get(file_path)
# 选择页面上所有的 input,然后从中过滤出所有的 checkbox 并勾选之
inputs = dr.find_elements_by_tag_name('input')
for input in inputs:
if input.get_attribute('type') == 'checkbox':
input.click()
time.sleep(2)
dr.quit()

注意:因为我们调用的是本地文件, 所以要导入 os 包。

1.2 、第二种定位方法

第二种写法与第一种写法差别不大,都是通过一个循环来勾选控件。
# -*- coding: utf-8 -*-
from selenium import webdriver
import time
import os
dr = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('checkbox.html')
dr.get(file_path)
# 选择所有的 checkbox 并全部勾上
checkboxes = dr.find_elements_by_css_selector('input[type=checkbox]')
for checkbox in checkboxes:
checkbox.click()
time.sleep(2)
# 打印当前页面上有多少个 checkbox
print len(dr.find_elements_by_css_selector('input[type=checkbox]'))
time.sleep(2)
dr.quit()

1.3 、去掉最后一个勾选

有时候我们并不想勾选页面的所有的复选框(checkbox),可以通 过下面办法把最后一个被勾选的框去掉。

可以进行如下修改:

# -*- coding: utf-8 -*-
from selenium import webdriver import time
import os
dr = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('checkbox.html')
dr.get(file_path) # 选择所有的 checkbox 并全部勾上
checkboxes = dr.find_elements_by_css_selector('input[type=checkbox]')
for checkbox in checkboxes:
checkbox.click()
time.sleep(2)
# 把页面上最后1个 checkbox 的勾给去掉
dr.find_elements_by_css_selector('input[type=checkbox]').pop().click()
time.sleep(2)
dr.quit() 

其实,去掉勾选表也逻辑也非常简单,就是再次点击勾选的按钮。可能我们比较迷惑的是如何找到“最后一个”按钮。pop() 可以实现这个功能。

pop()pop(-1):默认获取一组元素的最后一个

pop(0):默认获取一组元素的第一个

pop(1):默认获取一组元素的第二个

。。。

1.4、判断是否选中:is_selected()

1.有时候这个选项框,本身就是选中状态,如果我再点击一下,它就反选了,这可不是我期望的结果,那么可不可以当它是没选中的时候,我去点击下;
当它已经是选中状态,我就不点击呢?那么问题来了:如何判断选项框是选中状态?
2.判断元素是否选中这一步才是本文的核心内容,点击选项框对于大家来说没什么难度。获取元素是否为选中状态
3.返回结果为 bool 类型,没点击时候返回 False,点击后返回 True,接下来就很容易判断了,既可以作为操作前的判断,也可以作为测试结果的判断

2、多层框架/ 窗口定位
本节知识点:
多层框架或窗口的定位:

  • switch_to_frame()
  • switch_to_window()

对于一个现代的 web 应用,经常会出现框架(frame) 或窗口(window)的应用,这也就给我们的定位带来了一个难题。有时候我们定位一个元素,定位器没有问题,但一直定位不了,这时候就要检查这
个元素是否在一个 frame 中,seelnium webdriver 提供了一个 switch_to_frame 方法,可以很轻松的来解决这个问题。

2.1 、多层框架定位

frame.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/bootstra
p-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="f1" 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>

 

 inner.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="f2" src="http://www.baidu.com"
width="700"height="500"></iframe>
<a href="javascript:alert('watir-webdriver better than
selenium webdriver;')">click</a>
</div>
</div>
</body>
</html>

frame.html 中嵌套 inner.html ,两个文件和我们的脚本文件放同一个目录下,通过浏览器打开,得到下列页面:

下面通过 switch_to_frame() 方法来进行定位:

#coding=utf-8
from selenium import webdriver
import time
import os
browser = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('frame.html')
browser.get(file_path)
browser.implicitly_wait(30)
#先找到到 ifrome1(id = f1)
browser.switch_to_frame("f1")
#再找到其下面的 ifrome2(id =f2)
browser.switch_to_frame("f2")
#下面就可以正常的操作元素了
browser.find_element_by_id("kw").send_keys("selenium")
browser.find_element_by_id("su").click()
time.sleep(3)
browser.quit()

2.2 、多层窗口定位

(详细例子可以参考后面的,多窗口切换
有可能嵌套的不是框架,而是窗口,还有真对窗口的方法:switch_to_window用法与 switch_to_frame 相同:
driver.switch_to_window("windowName")

2.3、层级定位

假如两个控件,他们长的一模样,还都叫“张三”,唯一的不同是一个在北京,一个在上海,那我们就可以通过,他们的城市,区,街道,来找到他们。
在实际的测试中也经常会遇到这种问题:页面上有很多个属性基本相同的元素,现在需要具体定位到其中的一个。由于属性基本相当,所以在定位的时候会有些麻烦,这
时候就需要用到层级定位。先定位父元素,然后再通过父元素定位子孙元素。
level_locate.html

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>Level Locate</title>
<script type="text/javascript" async=""
src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></scri
pt>
<link
href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-c
ombined.min.css" rel="stylesheet" />
</head>
<body>
<h3>Level locate</h3>
<div class="span3">
<div class="well">
<div class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown"
href="#">Link1</a>
<ul class="dropdown-menu" role="menu"
aria-labelledby="dLabel" id="dropdown1" >
<li><a tabindex="-1" href="#">Action</a></li>
<li><a tabindex="-1" href="#">Another action</a></li>
<li><a tabindex="-1" href="#">Something else here</a></li>
<li class="divider"></li>
<li><a tabindex="-1" href="#">Separated link</a></li>
</ul>
</div>
</div>
</div>
<div class="span3">
<div class="well">
<div class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown"
href="#">Link2</a>
<ul class="dropdown-menu" role="menu"
aria-labelledby="dLabel" >
<li><a tabindex="-1" href="#">Action</a></li>
<li><a tabindex="-1" href="#">Another action</a></li>
<li><a tabindex="-1" href="#">Something else here</a></li>
<li class="divider"></li>
<li><a tabindex="-1" href="#">Separated link</a></li>
</ul>
</div>
</div>
</div>
</body>
<script
src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min
.js"></script>
</html>

上面的 html 代码比较乱,请复制到编辑器中查看,如 nodepad ++ 编辑器。

(注意,这个页面需要和我们的自动化脚本放在同一个目录下)通过浏览器打开:
定位思路:
具体思路是:先点击显示出1个下拉菜单,然后再定位到该下拉菜单所在的 ul,再定位这个 ul 下的某个具体的 link。在这里,我们定位第1个下拉菜单中的 Action 这个选项。
脚本如下:

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import time
import os
dr = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('level_locate.html')
dr.get(file_path)
#点击 Link1链接(弹出下拉列表)
dr.find_element_by_link_text('Link1').click()
#找到 id 为 dropdown1的父元素
WebDriverWait(dr, 10).until(lambda the_driver:
the_driver.find_element_by_id('dropdown1').is_displayed())
#在父亲元件下找到 link 为 Action 的子元素
menu = dr.find_element_by_id('dropdown1').find_element_by_link_text('Action')
#鼠标定位到子元素上
webdriver.ActionChains(dr).move_to_element(menu).perform()
time.sleep(2)
dr.quit()

WebDriverWait(dr, 10)

10秒内每隔500毫秒扫描1次页面变化,当出现指定的元素后结束。
is_displayed() :该元素是否用户可以见
driver: 执行用户操作实例 webdriver
class ActionChains(driver):生成用户的行为。所有的行动都存储在 actionchains 对象。通过 perform()存储的行为。
move_to_element(menu):移动鼠标到一个元素中,menu 上面已经定义了他所指向的哪一个元素
to_element:元件移动到
perform():执行所有存储的行为

selenium+Python(定位 单选、复选框,多层定位)的更多相关文章

  1. [SAP ABAP开发技术总结]选择屏幕——按钮、单选复选框

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  2. 个人永久性免费-Excel催化剂功能第58波-批量生成单选复选框

    插件的最大威力莫过于可以把简单重复的事情批量完全,对日常数据采集或打印报表排版过程中,弄个单选.复选框和用户交互,美观的同时,也能保证到数据采集的准确性,一般来说用原生的方式插入单选.复选框,操作繁琐 ...

  3. 吾八哥学Selenium(三):操作复选框checkbox/单选框radio的方法

    复选框checkbox和单选框radio是web网站里经常会使用到的两个控件,那么在web自动化测试的时候如何利用Selenium来操作这俩控件呢?今天我们就来简单入门练习一下! html测试页面代码 ...

  4. selenium--表格和复选框的定位

    表格定位 HTML代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...

  5. seleniumu 3.0复选框操作(定位一组元素)

    一般验证复选框是否可以选择点击常用到定位一组元素去循环遍历执行点击事件.但是有时候在不同的浏览器下可能会存在差异化的最终结果. 目前谷歌浏览器常常存在多次点击同一复选框,导致最终最后两项复选框均未被勾 ...

  6. 单选复选框的js代码取值

    单选框 复选框选中后的js代码处理 <script type="text/javascript"> function check(){ document.getElem ...

  7. Asp.net自定义单选复选框控件

    将常用的jquery插件封装成控件也是个不错的选择 下面是效果的简单颜色,由于博客系统的限制没法完整演示最终效果,请下载示例查看 Asp.netWeb APIC#Javascript   1.新建类库 ...

  8. [Selenium With C#基础教程] Lesson-07 复选框

    作者:Surpassme 来源:http://www.jianshu.com/p/98ede43da3c3 声明:本文为原创文章,如需转载请在文章页面明显位置给出原文链接,谢谢.   [作者:Surp ...

  9. FineReport——JS二次开发(复选框全选)

    在进行查询结果选择的时候,我们经常会用到复选框控件,对于如何实现复选框全选,基本思路: 在复选框中的初始化事件中把控件加入到一个全局数组里,然后在全选复选框里对数组里的控件进行遍历赋值. 首先,定义两 ...

  10. JQuery:JQuery基本语法,JQuery选择器,JQuery DOM,综合案例 复选框,综合案例 随机图片

    知识点梳理 课堂讲义 1.JQuery快速入门 1.1.JQuery介绍 jQuery 是一个 JavaScript 库. 框架:Mybatis (jar包) 大工具 插件:PageHelper (j ...

随机推荐

  1. 深入理解java虚拟机(十二) Java 语法糖背后的真相

    语法糖(Syntactic Sugar),也叫糖衣语法,是英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语.指的是,在计算机语言中添加某种语法,这些语法糖虽然不会对语言 ...

  2. MFC多线程详细讲解(转)

    一.问题的提出 编写一个耗时的单线程程序: 新建一个基于对话框的应用程序SingleThread,在主对话框IDD_SINGLETHREAD_DIALOG添加一个按钮,ID为IDC_SLEEP_SIX ...

  3. select2的一些隐藏功能

    select 3.5版本的说明文档里面存在 http://select2.github.io/select2/index.html option选项 sortResults query为查询字符串

  4. 20145233《网络对抗》Exp6 信息收集和漏洞扫描

    20145233<网络对抗>Exp6 信息收集和漏洞扫描 实验问题思考 哪些组织负责DNS,IP的管理 全球根服务器均由美国政府授权的ICANN统一管理,负责DNS和IP地址管理.全球一共 ...

  5. Arduino I2C + 温湿度传感器HTS221

    主要特性 HTS221是意法半导体(STMicroelectronics)生产的小体积.数字式温湿度传感器IC.该IC目前在官网仍处在“评估”状态.其主要特性: 工作电压:1.7~3.6V 数据输出频 ...

  6. 《html5 从入门到精通》读书笔记(一)

    今天看了<html5 从入门到精通>这本书,感觉阅读下来很舒心,不像阅读其他书籍很揪心.html增加的知识点,我觉得非常有价值,看完几章记录了一些内容,不但能巩固,也为下次遗忘知识点做好准 ...

  7. docker容器中安装vi

    容器中输入vi提示 root@e36f8029c9f2:/# vi bash: vi: command not found 解决办法: 1.通过命令获取最新的软件包 apt-get update ap ...

  8. WPF 实现INotifyPropertyChanged .Net Framework 4.5

    自己动手写了一个基类来实现INotifyPropertyChanged接口,以后可以直接使用. using System.ComponentModel; using System.Runtime.Co ...

  9. WPF 之 UI 异步交互

    System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(()=> { //··················· ...

  10. 比特币解锁脚本中的ScriptSignature都包含了什么东西

    比特币 解锁脚本signature script 包含了那些东西? 使用 UTXO 需要私钥签名,私钥到底都签了什么东西呢?一直比较好奇. 比特币的私钥签名总共有五中类型,具体见 btcd 代码,如下 ...