2019-10-21   更新

10 Webdriver 的页面元素处理
测者陈磊

测试技术的修炼之道

测者陈磊 · 前京东测试架构师

我好像是一只牛,吃的是草,挤出的是牛奶。

——鲁迅

Selenium WebDriver 是通过网页中页面上元素的 ID、Name、其它属性值等定位页面的 element,再通过流程串联完成各种各样的业务逻辑测试。在开发自动化测试脚本的过程中,自动化脚本的开发流程如下步骤所示:

  • 1 定位页面元素(唯一定位),获取对应元素的 element 对象;
  • 2 通过 element 对象的属性完成页面动作的操作(包含单击、双击等操作);
  • 3 通过 element 对象操作完成一些内容输入或者选取(例如输入文本、选择单选钮、选择多选框等)。

这三步应该是绝大部分的 WebUI 自动化步骤。但是这些都是要在第一步定位第一页面元素的基础之上,在很多人开发测试脚本的时候很多时候都找不到页面的 element,致使自动化测试还未开始就已经结束。

WebUI自动化脚本的神助攻利器

如何找到页面中各种 element 的定位元素,仅仅通过人工在 html 里面查找,那是一个费时费力的事情。因此我们需要一个工具帮我们完成 WebUI 上 element 的定位,这个工具就是浏览器,各大原生浏览器几乎都集成了对应的工具 firefox 的 web 开发者工具,chrome 的调试工具等。下面我们以 firefox 为例,在被测试系统的页面点击鼠标右键,选择“查看元素”,会弹出web开发者工具,选择如下图所示”从页面选择一个元素“功能:
图片描述下面我们按照慕课网的首页为例,通过 firefox 浏览器的 web 开发者工具识别购物车元素看一下,我们选择“从页面选择一个元素”功能,点击到慕课网首页右上角的购物车。
图片描述通过上图我们可以看到,在页面上购物车这个元素的 id 是 shop-cart,Class_Name 是 shop-cart。选中改行定位的 html 语句,点击右键选择复制,可以选择 XPATH,这也是 Selenium Webdriver 一种定位方式。

图片描述购物车元素的 XPath 路径是这样的 //*[@id="shop-cart"],通过元素的 XPath 的路径就可以定位到页面上的元素。那么我们该怎样根据元素的 XPath 路径进行元素定位呢?Selenium Webdriver 提供了一下几种方法:

  • find_element_by_id()
  • find_element_by_class_name()
  • find_element_by_css_selector()
  • find_element_by_link_text()
  • find_element_by_name()
  • find_element_by_partial_link_text()
  • find_element_by_tag_name()
  • find_element_by_xpath()

通过上面的几种方法,我们可以通过元素的文本、ID、CSS、标签名、XPath 路径等各种信息来定位元素。那么下面我们就来详细地看下这几种方法。

find_element_by_id()

这是一种最常用的元素定位方式,通过元素的 id 进行定位,方法名叫做 find_element_id() 。假设被测试代码片段如下所以(代码段来自慕课网):

<li class="shop-cart" id="shop-cart">
    <a href="//order.imooc.com/pay/cart" class="shop-cart-icon" target="_blank">
        <span class="icon-shopping-cart js-endcart"></span><span>购物车</span><span class="shopping_icon js-cart-num" data-ordernum="0" data-cartnum="0" style="display: none">0</span>
    </a>
    <div class="my-cart" id="js-my-cart"><div class="cart-title-box clearfix">                            
        <h2 class="l">我的购物车</h2>                            
            <h5 class="r">已加入<span class="js-incart-num">0</span>门课程</h5>                        
    </div>                        
    <div class="cart-wrap">                            
        <div class="clear-cart">                                
            <span class="cartIcon icon-shopping-cart"></span>                                
            <h3>购物车里空空如也</h3>                                
                <div class="text">快去这里选购你中意的课程</div>                                
                    <p><a class="go-link" href="//coding.imooc.com" target="_blank">实战课程</a></p>            <p><a class="go-link" href="//class.imooc.com/" target="_blank">就业班</a></p>            
                </div>                        
            </div>                        
            <div class="more-box clearfix">                            
                <div class="l show-box">                                
                    <span class="text"><a href="//order.imooc.com/myorder" target="_blank">我的订单中心</a></span>                            
                </div>                            
                <a href="//order.imooc.com/pay/cart" target="_blank" class="r moco-btn moco-btn-red go-cart">去购物车</a>                        
            </div>
        </div>
</li>

当要用 id 属性来引用这个购物车并单击它时,可以通过如下代码片段实现:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/12/24 10:45 AM
# @Author  : Mr.Tester Criss Chan
# @Site    : https://blog.csdn.net/crisschan
# @File    : auto_script.py

from selenium import webdriver#引入selenium的webdriver

driver = webdriver.Firefox()# 初始化一个driver
driver.get('https://www.imooc.com/')#访问慕课网首页
shopcart = driver.find_element_by_id('shop-cart')#找出购物车element
shopcart.click()# 点击购物车
driver.quit()# 退出driver

find_element_by_class_name()

find_element_by_class_name() 是利用 element 的 CSS 所引用的伪类名称来查找 element 的方法。对 于HTML 的 element 来说,前端开发工程师大部分都会给 element 直接赋予一个样式属性或者利用 CSS 文件中的伪类来定义 element 样式,这样在最后页面展示的时候,页面上的 element 会比较美观。一般 CSS 定义好后,就可以在页面 element 中引用。代码片段如下所示(引自慕课网首页):

.shop-cart .my-cart {
display: none;
width: 344px;
padding: 0px 16px;
position: absolute;
right: 0;
background: #fff;
box-sizing: border-box;
z-index: 99999;
box-shadow: 0 8px 16px 0 rgba(28, 31, 33, 0.2);
border-bottom-right-radius: 8px;
border-bottom-left-radius: 8px;
}

那么通过 class_name 定位到 element 的代码片段如下所示:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/12/24 10:45 AM
# @Author  : Mr.Tester Criss Chan
# @Site    : https://blog.csdn.net/crisschan
# @File    : auto_script.py

from selenium import webdriver#引入selenium的webdriver

driver = webdriver.Firefox()# 初始化一个driver
driver.get('https://www.imooc.com/')#访问慕课网首页
shopcart = driver.find_element_by_class_name('shop-cart')#找出购物车element
shopcart.click()# 点击购物车
driver.quit()# 退出driver

find_element_by_css_selector()

使用 css_selector 是官方推荐的方式,这是因为 css_selector 会比使用 XPath 更快。每一个 web 页面上的 element 都有一个样式,无论这个 element 多么复杂,多么花哨,css_selector 都可以定位得到,因此使用css_selector 也能非常准确地定位到页面上的 element 。同时 css_selector 可以适合并与各式各样的 element 的属性相结合使用。

  • 通过 tagname 完成 element 的选择:

    driver.find_element_by_css_selector('button')
    
  • 通过 class_name 定位 element:

    driver.find_element_by_css_selector('.shop-cart')
    
  • 应用 id 完成 element 的定位,找到购物车 :

    shopcart = driver.find_element_by_css_selector('#shop-cart')
    
  • 根据 element 的属性定位 element:

    • 使用 属性名=属性值 的方式定位element(访问慕课网课程页的搜索)

      #!/usr/bin/env python
      # -*- coding: utf-8 -*-
      # @Time    : 2019/12/24 10:45 AM
      # @Author  : Mr.Tester Criss Chan
      # @Site    : https://blog.csdn.net/crisschan
      # @File    : auto_script.py
      
      from selenium import webdriver#引入selenium的webdriver
      
      driver = webdriver.Firefox()# 初始化一个driver
      driver.get('https://www.imooc.com/course/list')#访问慕课网课程页
      search = driver.find_element_by_css_selector('input[class=search-input]')# 找到搜索(通过属性名=属性值的方式)
      search.click()
      driver.quit()# 退出driver
      
    • 存在属性(访问慕课网课程页,点击课程图标)

      #!/usr/bin/env python
      # -*- coding: utf-8 -*-
      # @Time    : 2019/12/24 10:45 AM
      # @Author  : Mr.Tester Criss Chan
      # @Site    : https://blog.csdn.net/crisschan
      # @File    : auto_script.py
      
      from selenium import webdriver#引入selenium的webdriver
      
      driver = webdriver.Firefox()# 初始化一个driver
      driver.get('https://www.imooc.com/course/list')#访问慕课网课程页
      course_page_logo = driver.find_element_by_css_selector('img[alt]')# img下存在alt,找到这个element
      course_page_logo.click()
      driver.quit()# 退出driver
      
    • 多属性(访问慕课网课程页,点击课程图标)

      #!/usr/bin/env python
      # -*- coding: utf-8 -*-
      # @Time    : 2019/12/24 10:45 AM
      # @Author  : Mr.Tester Criss Chan
      # @Site    : https://blog.csdn.net/crisschan
      # @File    : auto_script.py
      
      from selenium import webdriver#引入selenium的webdriver
      
      driver = webdriver.Firefox()# 初始化一个driver
      driver.get('https://www.imooc.com/course/list')#访问慕课网课程页
      course_page_logo = driver.find_element_by_css_selector('img[alt="课程"][height="60"]')# img多个属性同时定位elemt
      ourse_page_logo.click()        
      driver.quit()# 退出driver
      
  • 通过正则表达式完成模糊定位:

    • 前缀以固定匹配开始(访问慕课网课程页的搜索)

      #!/usr/bin/env python
      -*- coding: utf-8 -*-
      @Time    : 2019/12/24 10:45 AM
      @Author  : Mr.Tester Criss Chan
      @Site    : https://blog.csdn.net/crisschan
      @File    : auto_script.py
      
      

from selenium import webdriver#引入selenium的webdriver
driver = webdriver.Firefox()# 初始化一个driver
driver.get(‘https://www.imooc.com/course/list’)#访问慕课网课程页
search = driver.find_element_by_css_selector(‘input[class^=“search”]’)# 找到搜索(通过属性名=属性值的方式)
search.click()
driver.quit()# 退出driver

     
  - 后缀以固定匹配开始(访问慕课网课程页的搜索)
  
    ```python
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Time    : 2019/12/24 10:45 AM
    # @Author  : Mr.Tester Criss Chan
    # @Site    : https://blog.csdn.net/crisschan
    # @File    : auto_script.py
    
    from selenium import webdriver #引入selenium的webdriver
    
    driver = webdriver.Firefox() # 初始化一个driver
    driver.get('https://www.imooc.com/course/list') #访问慕课网课程页
  search = driver.find_element_by_css_selector('input[class$="search-inpu"]') # 找到搜索(通过属性名=属性值的方式)
    search.click()
    driver.quit()# 退出driver
  • 中间以固定匹配(访问慕课网课程页的搜索):

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Time    : 2019/12/24 10:45 AM
    # @Author  : Mr.Tester Criss Chan
    # @Site    : https://blog.csdn.net/crisschan
    # @File    : auto_script.py
    
    from selenium import webdriver#引入selenium的webdriver
    
    driver = webdriver.Firefox()# 初始化一个driver
    driver.get('https://www.imooc.com/course/list')#访问慕课网课程页
    search = driver.find_element_by_css_selector('input[class*="search"]')# 找到搜索(通过属性名=属性值的方式)
    search.click()
    driver.quit()# 退出driver
    

find_element_by_link_text() 是通过超文本链接上的文字来定位 element 的,这是一种专门提供定位文本超链接的 element 的方法。具体如下代码片段所示(如下代码片段来自慕课网课程页):

<div class="page">
    <span class="disabled_page">首页</span>
    <span class="disabled_page">上一页</span>
    <a href="javascript:void(0)" class="active text-page-tag">1</a>
    <a class="text-page-tag" href="/course/list?page=2">2</a>
    <a class="text-page-tag" href="/course/list?page=3">3</a>
    <a class="text-page-tag" href="/course/list?page=4">4</a>
    <a class="text-page-tag" href="/course/list?page=5">5</a>
    <a class="text-page-tag" href="/course/list?page=6">6</a>
    <a class="text-page-tag" href="/course/list?page=7">7</a>
    <a href="/course/list?page=2">下一页</a>
    <a href="/course/list?page=30">尾页</a>
</div>

要针对上述代码,找到第二页的element如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/12/24 10:45 AM
# @Author  : Mr.Tester Criss Chan
# @Site    : https://blog.csdn.net/crisschan
# @File    : auto_script.py

from selenium import webdriver#引入selenium的webdriver
   
 driver = webdriver.Firefox()# 初始化一个driver
driver.get('https://www.imooc.com/course/list')#访问慕课网课程页
next_page = driver.find_element_by_link_text('2')

print(next_page.text)

driver.quit()# 退出driver

find_element_by_partial_link_text() 方法是上面 find_element_by_link_text() 方法的扩展,如果在定义一个element 时,我们仅仅知道一些关键字,那么可以使用这个方法,通过关键字完成 element 的定位。具体如下代码片段所示(如下代码片段来自慕课网课程页):

<div class="page">
    <span class="disabled_page">首页</span>
    <span class="disabled_page">上一页</span>
    <a href="javascript:void(0)" class="active text-page-tag">1</a>
    <a class="text-page-tag" href="/course/list?page=2">2</a>
    <a class="text-page-tag" href="/course/list?page=3">3</a>
    <a class="text-page-tag" href="/course/list?page=4">4</a>
    <a class="text-page-tag" href="/course/list?page=5">5</a>
    <a class="text-page-tag" href="/course/list?page=6">6</a>
    <a class="text-page-tag" href="/course/list?page=7">7</a>
    <a href="/course/list?page=2">下一页</a>
    <a href="/course/list?page=30">尾页</a>
</div>

我们使用该方法,定位下一页这个element:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/12/24 10:45 AM
# @Author  : Mr.Tester Criss Chan
# @Site    : https://blog.csdn.net/crisschan
# @File    : auto_script.py

from selenium import webdriver#引入selenium的webdriver
   
driver = webdriver.Firefox()# 初始化一个driver
driver.get('https://www.imooc.com/course/list')#访问慕课网课程页
next_page = driver.find_element_by_partial_link_text('下一')

print(next_page.text)

driver.quit()# 退出driver

find_element_by_name()

find_element_by_name() 是通过 name 属性定位 element,这个方法和 find_element_by_id() 方法一样,是一个使用相对比较频繁的方法。具体使用如下代码段所示(代码来自慕课网的登录页):

<div class="rlf-group pr">
	<input type="text" value="" maxlength="37" name="email" data-validate="require-mobile-phone" autocomplete="off" class="xa-emailOrPhone ipt ipt-email js-own-name" placeholder="请输入登录手机号/邮箱">
    <p class="rlf-tip-wrap errorHint color-red" data-error-hint="请输入正确的邮箱或手机号"></p>	
</div>

我们使用该方法定位这个 element:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/12/24 10:45 AM
# @Author  : Mr.Tester Criss Chan
# @Site    : https://blog.csdn.net/crisschan
# @File    : auto_script.py

from selenium import webdriver#引入selenium的webdriver
import time
driver = webdriver.Firefox()# 初始化一个driver
driver.get('http://www.imooc.com/user/newlogin')#访问慕课网课程页
user_name = driver.find_element_by_name('email')# 通过email的name定位用户名的输入框
user_name.send_keys('mr_tester@mr.tester.com')# 输入用用户名
driver.quit()# 退出driver

find_element_by_tag_name()

find_element_by_tag_name() 函数提供了通过 tag 的 name 来定位 element 的方法,具体使用如下代码段所示(代码来自慕课网的登录页):

<div class="rlf-group pr">
	<input type="text" value="" maxlength="37" name="email" data-validate="require-mobile-phone" autocomplete="off" class="xa-emailOrPhone ipt ipt-email js-own-name" placeholder="请输入登录手机号/邮箱">
    <p class="rlf-tip-wrap errorHint color-red" data-error-hint="请输入正确的邮箱或手机号"></p>	
</div>

我们使用该方法定位这个 element:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/12/24 10:45 AM
# @Author  : Mr.Tester Criss Chan
# @Site    : https://blog.csdn.net/crisschan
# @File    : auto_script.py

from selenium import webdriver#引入selenium的webdriver
import time
driver = webdriver.Firefox()# 初始化一个driver
driver.get('http://www.imooc.com/user/newlogin')#访问慕课网课程页

user_name = driver.find_element_by_tag_name('input')# 通过tag_name定位用户名输入框
user_name.send_keys('mr_tester')
driver.quit()# 退出driver

find_element_by_xpath()

Xpath 是 XML Path 的简称,我们可以借助于 XPath 完成 element 的定位,这种方式是最不提倡的方式,要是用 xpath 完成定位,webdrive 会依据全部页面进行扫描,来找到对应的元素,全部查找过程非常耗费时间,如果一个脚本中存在大量的 xpath,会大大影响脚本的执行效率。具体使用如下代码段所示(代码来自慕课网的登录页):

<div class="rlf-group pr">
	<input type="text" value="" maxlength="37" name="email" data-validate="require-mobile-phone" autocomplete="off" class="xa-emailOrPhone ipt ipt-email js-own-name" placeholder="请输入登录手机号/邮箱">
    <p class="rlf-tip-wrap errorHint color-red" data-error-hint="请输入正确的邮箱或手机号"></p>	
</div>

我们使用该方法定位这个element:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/12/24 10:45 AM
# @Author  : Mr.Tester Criss Chan
# @Site    : https://blog.csdn.net/crisschan
# @File    : auto_script.py

from selenium import webdriver#引入selenium的webdriver
import time
driver = webdriver.Firefox()# 初始化一个driver
driver.get('http://www.imooc.com/user/newlogin')#访问慕课网课程页

user_name = driver.find_element_by_xpath('/html/body/div[2]/div/div/div[2]/div/form/div[1]/input')# 通过tag_name定位用户名输入框
user_name.send_keys('mr_tester')

driver.quit()# 退出driver

虽然 XPath 是最不推荐的方法,但很多时候我们又不得不使用该方法,那么这就要是我们必须看得懂 XPath 的语法,具体 XPath 语法的学习大家自行寻找就好了,这个网上很多,就不在此一一赘述了。在实际工作中,我们往往借助于本次课程开始部分的浏览器辅助工具直接选中对应的 element 然后辅助 XPath , 就可以直接在自动化测试脚本中使用了。

Selenium WebDriver的等待

在我们访问一个网页的时候,请求是从客户端浏览器发出,经历中间网络传输到达服务器端,服务器端经过分析处理,然后将返回消息通过网络发送给客户端浏览器上,浏览器经过渲染后展示给最终用户。这个全部过程都会消耗时间,无论是因为网络延时,还是因为处理时间长,都会导致找不到 element。这种情况就需要等待,让脚本等一等 web 页面上的 element 显示出现。WebDriver 的等待有如下三种:

  • 强制等待
  • 隐式等待
  • 显式等待

下面针对上面的三种等待方式,我们详细做一下说明:

强制等待

强制等待其实不是 Selenium Webdriver 提供的,而是通过 python 的 time 模块的 sleep 实现的,我们通过调用 sleep 方法让脚本在某一个流程中强制暂停几秒钟。假设被测试代码片段如下所以(代码段来自慕课网首页):

<li class="shop-cart" id="shop-cart">
    <a href="//order.imooc.com/pay/cart" class="shop-cart-icon" target="_blank">
        <span class="icon-shopping-cart js-endcart"></span><span>购物车</span><span class="shopping_icon js-cart-num" data-ordernum="0" data-cartnum="0" style="display: none">0</span>
    </a>
    <div class="my-cart" id="js-my-cart"><div class="cart-title-box clearfix">                            
        <h2 class="l">我的购物车</h2>                            
            <h5 class="r">已加入<span class="js-incart-num">0</span>门课程</h5>                        
    </div>                        
    <div class="cart-wrap">                            
        <div class="clear-cart">                                
            <span class="cartIcon icon-shopping-cart"></span>                                
            <h3>购物车里空空如也</h3>                                
                <div class="text">快去这里选购你中意的课程</div>                                
                    <p><a class="go-link" href="//coding.imooc.com" target="_blank">实战课程</a></p>            <p><a class="go-link" href="//class.imooc.com/" target="_blank">就业班</a></p>            
                </div>                        
            </div>                        
            <div class="more-box clearfix">                            
                <div class="l show-box">                                
                    <span class="text"><a href="//order.imooc.com/myorder" target="_blank">我的订单中心</a></span>                            
                </div>                            
                <a href="//order.imooc.com/pay/cart" target="_blank" class="r moco-btn moco-btn-red go-cart">去购物车</a>                        
            </div>
        </div>
</li>

当要用 id 属性来引用这个购物车并单击它时,可以通过如下代码片段实现:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/12/24 10:45 AM
# @Author  : Mr.Tester Criss Chan
# @Site    : https://blog.csdn.net/crisschan
# @File    : auto_script.py

from selenium import webdriver#引入selenium的webdriver

driver = webdriver.Firefox()# 初始化一个driver
driver.get('https://www.imooc.com/')#访问慕课网首页
time.sleep(3)# 强制等待3秒钟
shopcart = driver.find_element_by_id('shop-cart')#找出购物车element
shopcart.click()# 点击购物车
driver.quit()# 退出driver

虽然引入time.sleep()可以实现,但是如果我们每一个步骤都等待3秒钟,那么全部脚本执行就需要很多的时间去等待,time.sleep() 的方式是进程的挂起时间,这段时间进程什么都不做,就在等待。这明显不是一个好方式,但是却能够快速完成等待的预期结果。

隐式等待

在 Selenium Webdriver 中提供了一种隐式等待的方式,implicitly_wait(),这种方法比 time.sleep() 的方式更加智能,implicitly_wait() 可以设置成在一个时间范围内等待,假设设计了 implicitly_wait(10),也就是说所有的find_element 方法都会隐式等待 10 秒钟,要么在 10 秒钟内找到了 element 继续执行,要么等待10秒钟没有出现目标的 element 报错。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/12/24 10:45 AM
# @Author  : Mr.Tester Criss Chan
# @Site    : https://blog.csdn.net/crisschan
# @File    : script.py

from selenium import webdriver#引入selenium的webdriver
from selenium.webdriver.support.ui import WebDriverWait
import time
driver = webdriver.Firefox()# 初始化一个driver
driver.implicitly_wait(10)#隐式等待10秒钟
driver.get('http://www.imooc.com/')#访问慕课网课程页

driver.quit()# 退出driver

显式等待

WebDriverWait 时显示等待,这也是我们介绍的第一个不是通过 from selenium 引入的包,它通过 from selenium.webdriver.support.ui import WebDriverWait 引入。WebDriverWait 明确地要等到某个条件满足后执行,或者一直等到时间超时后报异常。Selenium 会0.5秒进行一次 webUI 的扫描,已确定页面上是否已经出现了我们需要做的元素并且完成了对应动作。如下所示:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/12/24 10:45 AM
# @Author  : Mr.Tester Criss Chan
# @Site    : https://blog.csdn.net/crisschan
# @File    : script.py

from selenium import webdriver#引入selenium的webdriver
from selenium.webdriver.support.ui import WebDriverWait# 引入显示等待
from selenium.webdriver.support import expected_conditions as EC# 引入expected_conditions的类,并用EC在脚本用引用
from selenium.webdriver.common.by import By# 引入By的类
driver = webdriver.Firefox()# 初始化一个driver

driver.get('http://www.imooc.com/')#访问慕课网课程页
loctor = (By.ID,'shop-cart')
try:
    shop_cart = WebDriverWait(driver,10).until(EC.presence_of_element_located(loctor))# shop-cart元素在首页加载的时候是否能够在10内出现
    shop_cart.click()# 如果在10秒内出现,那么就点击shop_cart
except:
    print("shop cart can't find")# 如果没出现会打印没后找到购物者这个element
finally:
    driver.quit()# 退出浏览器无论是否找到购物车element,都要最后退出
EC是expected_conditions的别名,通过AS方便在代码中使用,EC(expected_conditions)提供各种各样的判定方法,那么我们下面详细介绍一下EC(expected_conditions)都提供了什么的判定方法

title_is()

title_is() 是提供检测当前页面的 title 是不是和我们预期的一致,如果一致返回 True,否则返回 False,使用代码片段如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/12/24 10:45 AM
# @Author  : Mr.Tester Criss Chan
# @Site    : https://blog.csdn.net/crisschan
# @File    : auto_script.py

from selenium import webdriver#引入selenium的webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Firefox()# 初始化一个driver
driver.get('http://www.imooc.com/')#访问慕课网课程页
title_is=EC.title_is('慕课网-程序员的梦工厂')#初始化页面的title
print(title_is(driver))#判定是不是和预期一直
driver.quit()# 退出driver

title_contains()

title_contains() 检查当前页面的 title 是不是包含给出的关键字,如果包含返回 True,否则返回 False,使用代码片段如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/12/24 10:45 AM
# @Author  : Mr.Tester Criss Chan
# @Site    : https://blog.csdn.net/crisschan
# @File    : auto_script.py

from selenium import webdriver#引入selenium的webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()# 初始化一个driver

driver.get('http://www.imooc.com/')#访问慕课网课程页

title_contains=EC.title_contains('慕课网')# 页面的额title包含”慕课网”三个字

print(title_contains(driver))

driver.quit()# 退出driver

presence_of_element_located()

presence_of_element_located() 是用来判断某个 element 是不是已经在 Dom 树中出现的检测方法,在 Dom树中出现并不代表可以在页面上看见。使用方法如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/12/24 10:45 AM
# @Author  : Mr.Tester Criss Chan
# @Site    : https://blog.csdn.net/crisschan
# @File    : auto_script.py

from selenium import webdriver#引入selenium的webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

driver = webdriver.Firefox()# 初始化一个driver

driver.get('http://www.imooc.com/')#访问慕课网课程页

shop_cart = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "shop-cart")))# 等待购物车的element在dom中出现,如果10秒钟没出现就报错

driver.quit()# 退出driver

element_to_be_clickable()

element_to_be_clickable() 用来判断对应的元素是不是可操作的(输入、点击等)。如果出现并且可操作那么会返回对应WebElement的实例,否则报错:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/12/24 10:45 AM
# @Author  : Mr.Tester Criss Chan
# @Site    : https://blog.csdn.net/crisschan
# @File    : auto_script.py

from selenium import webdriver#引入selenium的webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Firefox()# 初始化一个driver
driver.get('http://www.imooc.com/')#访问慕课网课程页
shop_cart = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "shop-cart")))#等到出现可操作的id是shop-cart的element
driver.quit()# 退出driver

visibility_of_element_located()

visibility_of_element_located() 方法作用就是等要找的 element 出现,并且可见后,才会返回对应的 WebElement 实例,实例代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/12/24 10:45 AM
# @Author  : Mr.Tester Criss Chan
# @Site    : https://blog.csdn.net/crisschan
# @File    : auto_script.py

from selenium import webdriver#引入selenium的webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Firefox()# 初始化一个driver
driver.get('http://www.imooc.com/')#访问慕课网课程页
shop_cart = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "shop-cart")))# 等待id为shopt-cart的elemnt出现
driver.quit()# 退出driver

弹出框

针对页面的弹出框,一共有三种方式(主要是以 JavaScript 完成的),这三种分别是警告、确认和提示。

警告

JavaScrip t的警告框只有一个确定按钮,点击确定后无返回值,主要是为了提供一个警示性的说明。警告框是一个模式化弹出框,这也就要求必须点击确定后才可以进行后续操作,代码如下所示:

alert("请注意,前方危险~~~");

脚本实现自动化的方式如下:

alert = driver.switch_to.alert()
alert.accept()

确认

确认的弹出框上会出现确定和取消按钮,分别对应了 true 和 false 的返回值,主要用来确定用户是否接受了某些条款类信息等。当确认框出现后,在 UI 交互上需要用户点击确定或者取消完成交互后才能进行后续流程,同警告框一下,确认框也是一个模式化弹出框。如果在弹出框中用户点击确定,那么会返回 true,点击取消,会返回false。代码如下所示:

confirm("是否同意本条款")

脚本实现自动化的方式如下:

confirm_alert = driver.switch_to.alert()## 选择确认弹出框
confirm_text = confirm_alert.text()## 获取确认弹出框的文本
confirm_alert.accept()## 点击确认按钮

提示

提示弹出框会返回输入的内容,或者会返回一个默认值。提示弹出框大部分用于提醒用户在进入页面前输入某个值,当提示弹出框弹出后,一般都是需要用户输入某些信息,然后点击确定或者取消完成交互后才能继续下面的业务流程,这么说提示弹出框也是一个模式对话框。如果用户单击“确认”按钮,那么返回值为输入的值。如果用户单击“取消” 按钮,那么返回值为 null。

prompt("请输入您的姓名", "比尔盖茨");

脚本实现自动化的方式如下:

prompt_alert = driver.switch_to.alert()## 选择确认弹出框
prompt_alert.send_key('Mr.Tester CrissChan')
prompt_alert.accept()## 点击确认按钮

如果要按取消按钮,调用的函数是dismiss()。

小结

本部分我们介绍了如何应用浏览器的对应功能完成 element 的查找,同时介绍了 webdriver 的各种 element 的定位方法,在文中笔者给出了推荐使用的 element 定位访问。然后我们介绍了各种等待以及优越,到底选择哪一种要具体情况具体分析,最后我们介绍了各种弹出框的处理方法。学习好本部分的内容,你应该可以解决绝大部分脚本的开发问题,其它个性化的问题如果需要请自行查找。后面我们会针对使用 Webdriver 中一些常见的问题进行一下阐述以及如何避免的方法介绍。

0 / 2
登录后可任选 2 个小节免费阅读
课程目录
取消 评论 发送