实 验 简 介
在前面的实验中,我们一直在使用findElement()方法结合By对象完成Web页面元素的识别,这也是WebDriver最为核心的API之一。
本节实验就主要来探讨关于findElement()系列API的详细用法,帮助大家更清楚的理解具体的实现机制,以便于在真实项目中更加有针对性的对该系列API进行灵活的运用,达到精准定位Web页面元素的目的。
实 验 目 的
(1)理解Web页面的DOM操作接口规范及元素定位机制。
(2)理解findElement()和findElements()的区别及用法。
(3)理解By对象的linkText()和partialLinkText()方法的实现原理。
(4)理解By对象的cssSelector()方法的实现机制。
(5)理解By对象的xpath()方法的实现机制及XPath的定位原理。
(6)能够充分应用上述对象识别机制结合具体实例进行灵活的对象处理。
实 验 流 程
1.Web页面中的DOM规范
DOM全称是Document Object Model(文档对象模型),是为HTML和XML提供的一套操作文档元素的标准API接口。那么为什么DOM可以同时提供给HTML和XML编程接口。虽然他们用来标记的标签不同,但是他们本质的结构是相同的。换句话说,按照DOM的标准,HTML和XML都是以标签为结点构造的树结构,DOM将HTML和XML的相同的结构本质抽象出来,然后通过脚本语言,如JavaScript,按照DOM里的模型标准访问和操作文档内容。
本节内容并不专门探讨Web前端开发里面的DOM细节,而是将重点专注在如何利用DOM接口规范完成对页面元素的定位。通常情况下,针对页面元素的定位主要通过以下四种手段进行:
(1)标签选择器:直接利用页面元素的标签名称来获取到某一个或多个元素。
(2)ID选择器:利用某个元素的ID属性完成元素的定位,ID选择器只会定位到唯一的一个元素。
(3)Class类选择器:利用元素的Class属性来获取到某一个或多个元素。
(4)Name属性:根据Name属性来完成定位。
(5)XPath选择器:目前在DOM中使用的频率较低,但是提供了接口支持。
(6)组合选择器:综合利用上述各选择器结合层次关系等进行的混合定位。
2.利用JavaScript操作DOM
我们先来看一段笔者制作的一个基于HTML+CSS+JavaScript的倒计时程序的代码片段,读者可在本章配套源代码中找到完整的代码实现。该倒计时程序的运行结果如图所示。
此处我们只截取HTML页面布局的一部分内容,不关注JavaScript代码功能实现及CSS样式,而只是利用JavaScript结合HTML页面元素为大家简单演示一下如何进行定位。具体的代码如下:
<html> <p/><p/>祝各位参赛选手取得优秀成绩! |
3.利用WebDriver定位元素
WebDriver为我们提供了两个关键API用于定位一个或一批元素:
(1)driver.find_element_by_:返回一个类型为WebElement的元素,如果By对象找到了多个元素,则返回第一个被找到的元素,如果By对象没有找到元素,则抛出异常。
(2)driver.find_elements_by_:返回一个类型为List集合,即多个元素,如果by对象只找到一个元素,仍然是一个List集合,只是该List对象的size为1而已,如果by对象没有找到元素,则抛出异常。
我们来看看具体的实例:
from selenium import webdriver #引入webdriver
driver = webdriver.Firefox(firefox_binary=r"C:\Program Files (x86)\Mozilla Firefox\firefox.exe") #实例化Firefox 的driver对象 driver.get(‘http://localhost:8080/WoniuSales/ ustomer’) #打开蜗牛进销存进入会员管理模块 #会员手机号输入框提供id属性且唯一,找到该输入框,并输入手机号
driver.find_element_by_id(‘customerphone’).send_keys(‘18781163070’)
#操作按钮有3个,可以通过tag_name的方式将它们全部找到 li = driver.find_elements_by_tag_name(‘button’) print(len(li)) |
find_element或者find_elements这都是driver如何查找找页面元素的方法,by_后面的方法才是页面上元素被定位的方式。
4.通过找到id值的方式定位元素
id是HTML中标签中的属性的一种,如百度首页里输入框代码:
<input id="kw" name="wd" value="" maxlength="255" autocomplete="off"> |
从上面的代码中可以看到,input标签中有属性id=”kw”,联系上下文可以发现此属性的值也就是“kw”只在该标签中出现是唯一的。
这种具有唯一性的属性可以准确的定位到该input标签,所以在webdriver中,我们常用driver.find_element_by_id()的方式来定位元素。
from selenium import webdriver import time driver = webdriver.Firefox(firefox_binary=r"C:\Program Files (x86)\Mozilla Firefox\firefox.exe") driver..get(‘http://www.baidu.com’) time.sleep(2) #让程序等来2秒 driver..find_element_by_id(‘kw’).send_keys(‘蜗牛学院’) #在输入框内填写‘蜗牛学院’ |
但是,不是所有id都可以使用。有些html页面中标签虽然有id的属性,但是每次打开源码会发现id的值是变化的。这是由于UI设计人员在页面里面使用前端技术实现的动态ID。遇到这种情况,想要通过id属性定位元素就不可能实现了。
5.通过找到name属性的值的方式定位
如果遇到id的值是动态生成,那么大家可以在HTML代码中找找,看看是否还有name属性,一般来说,该属性使用动态生成的可能不大。所以,如果你要找的页面元素具有name属性,那么大家可以使用driver.find_element_by_name()的方法来定位这个页面元素。如上图x-x所示,input标签不仅有id属性,同时也具有name属性,其name属性的值是“wd”,那么,想要向该输入框内填入数据代码可以这样修改:
from selenium import webdriver import time driver = webdriver.Firefox(firefox_binary=r"C:\Program Files (x86)\Mozilla Firefox\firefox.exe") driver..get(‘http://www.baidu.com’) time.sleep(2) #让程序等来2秒 driver..find_element_by_name (‘wd’).send_keys(‘蜗牛学院’) #在输入框内填写‘蜗牛学院’ |
从前面的代码可以看出,无论使用id还是name,它们都有一个共同的特点,选取标签属性的时候都必须保证属性在整个HTML中是唯一的。如果标签内没有这些属性或者属性,前面的定位方式就无法使用了。
下周分享:核心实验:Selenium WebDriver->对象识别机制(二)