zoukankan      html  css  js  c++  java
  • selenium+Python(定位 单选、复选框,多层定位)

    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():执行所有存储的行为

  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    用 C 语言开发一门编程语言 — 字符串与文件加载
    用 C 语言开发一门编程语言 — 条件分支
    PTA刷题笔记(C语言) | 7-38 支票面额 (15分)
    PTA刷题笔记(C语言) | 7-33 统计素数并求和 (20分)
  • 原文地址:https://www.cnblogs.com/101718qiong/p/7403556.html
Copyright © 2011-2022 走看看