Selenium WebDriver Api 知识梳理

之前一直没有系统的梳理WebDriver Api的相关知识,今天借此机会整理一下。

1、页面元素定位

  1.1、8种常用定位方法  

1.2、实例

以百度输入框为例如下图

#id定位driver.find_element_by_id('kw')#name定位driver.find_element_by_name('wd')#className定位driver.find_element_by_class_name('s_ipt')#tag定位driver.find_element_by_tag_name('input')

注意:由于name、class 、tag等不具有唯一性,所以不能区分不同的元素,所以很少使用。

link定位与前面介绍的几种定位方法有所不同,它专门用来定位本链接。百度输入框上面的几个文本

链接的代码如下:

新闻hao123地图视频

贴吧>

通过查看上面的代码,我们发现通过name属性定位是个不错的选择。不过我们这里为了要学习link

定位,通过link定位实现如下:

find_element_by_link_text("新闻")find_element_by_link_text("hao123")find_element_by_link_text("地图")find_element_by_link_text("视频")find_element_by_link_text("贴吧")

通过partial link定位如下:

find_element_by_partial_link_text("一个很长的")find_element_by_partial_link_text("文本连接")

find_element_by_link_text()方法通过元素标签对之间的部分文本信息来定位元素。

xpath 、css定位

#xpath定位driver.find_element_by_xpath('//*[@id="kw"]')#css定位driver.find_element_by_css_selector('#kw')

通过class属性定位:

find_element_by_css_selector(".s_ipt")find_element_by_css_selector(".bg s_btn")

find_element_by_css_selector()方法用于CSS语言定位元素,点号(.)表示通过class属性来定位元素。

通过id属性定位:

find_element_by_css_selector("#kw")find_element_by_css_selector("#su")

井号(#)表示通过id属性来定位元素

  1.3、定位一组元素

WebDriver还

提供了与之对应的8种定位方法用于定位一组元素。

find_elements_by_id()find_elements_by_name()find_elements_by_class_name()find_elements_by_tag_name()find_elements_by_link_text()find_elements_by_partial_link_text()find_elements_by_xpath()find_elements_by_css_selector()

定位一组对象的方法与定位单个对象的方法类似,唯一的区别是在单词element后面多了一个s表示

复数。

定位一组对象一般用于以下场景:

批量操作对象,比如将页面所有的复选框都被勾选。

先获取一组对象,再在这组对象中过滤出需要具体定位的一些对象。比如定位出页面上所有的

checkbox,然后选择最后一个。

如下图通过 css 定位出一组元素,然后获取对应文本,判断是否是自己需要的,然后获取对应下标。

fac_list = self.driver.find_elements_by_css_selector(".w220.ellipsis")forfacinfac_list:iffac.text == u'洛阳顺势药业有限公司': i=fac_list.index(fac) i= i+1breakgoogs_path=".//*[@id='search_result_list']/li[%d]/div/table/tbody/tr[1]/td[9]/p/a"%i time.sleep(5)

以上完成了页面元素简单定位,当然这里只是最简单的举例,复杂的定位可以根据需要进行组合,当然也可以借助浏览器插件等工具,进行元素定位,如chrome 的开发者模式,firefox 的 firebug、firepath等工具

2、浏览器操作

  2.1、控制浏览器大小

#设置浏览器大小driver.set_window_size(800,800)#设置浏览器最大化driver.maximize_window()

  2.2、控制浏览器后退、前进、刷新

#FileName : setWindow.py#Author : Adil#DateTime : 2018/3/12 16:48#SoftWare : PyCharmfromseleniumimportwebdriverimporttimedriver=webdriver.Chrome()driver.implicitly_wait(1)first_url="http://www.baidu.com/"driver.get(first_url)time.sleep(5)#设置浏览器大小driver.set_window_size(800,800)#设置浏览器最大化driver.maximize_window()#访问第二个页面second_url ='http://news.baidu.com/'driver.get(second_url)#返回(后退)到百度首页print("back to %s"%first_url)#back to http://www.baidu.com/driver.back()#前进到新闻页print("forward to %s"% second_url)#forward to http://news.baidu.com/driver.forward()time.sleep(5)driver.refresh()time.sleep(15)driver.quit()

  2.3、浏览器滚动

关于浏览器滚动条的滚动,之前,chrome与其他浏览器是不兼容的,

参考 http://www.cnblogs.com/Skyyj/p/7275938.html

今天尝试发现,chrome 与其他浏览器兼容了,改变了原有的写法。

上下滚动统一支持如下写法

#滚动到底部js="var q=document.documentElement.scrollTop=10000"driver.execute_script(js)time.sleep(5)#然后滚动到上面js="var q=document.documentElement.scrollTop=0"driver.execute_script(js)

左右滚动

#设置浏览器窗口大小,长500,高400driver.set_window_size(500,400)time.sleep(5)#设置横向滚动js ='window.scrollTo(500,400)'driver.execute_script(js)time.sleep(5)

3、元素操作

  3.1、元素简单操作

click() 单击、clear()清空、send_keys()文本框输入、submit()提交表单,模拟回车操作

driver.find_element_by_id("idInput").clear()driver.find_element_by_id("idInput").send_keys("username")driver.find_element_by_id("pwdInput").clear()driver.find_element_by_id("pwdInput").send_keys("password")driver.find_element_by_id("loginBtn").click()

  3.2、鼠标事件

ActionChains类提供的鼠标操作的常用方法:

perform() 执行所有 ActionChains 中存储的行为

context_click() 右击

double_click() 双击

drag_and_drop() 拖动

move_to_element() 鼠标悬停

#FileName : mouseSet.py#Author : Adil#DateTime : 2018/3/12 18:32#SoftWare : PyCharmfromseleniumimportwebdriver#import ActionChainsfromselenium.webdriver.common.action_chainsimportActionChainsimporttimedriver=webdriver.Chrome()#driver.implicitly_wait(1)first_url="http://www.baidu.com/"driver.get(first_url)#悬浮 move_to_element()time.sleep(2)driver.maximize_window()time.sleep(2)element1= driver.find_element_by_xpath(".//*[@id='u1']/a[8]")ActionChains(driver).move_to_element(element1).perform()time.sleep(5)#右击 context_click()ActionChains(driver).context_click(element1).perform()time.sleep(5)#双击 double_click()ActionChains(driver).double_click(element1).perform()time.sleep(5)#拖动 drag_and_drop()#定位元素的源位置element = driver.find_element_by_name("xxx")#定位元素要移动到的目标位置target = driver.find_element_by_name("xxx")#执行元素的拖放操作ActionChains(driver).drag_and_drop(element,target).perform()driver.quit()

  3.3、键盘事件

from selenium.webdriver.common.keys import Keys

在使用键盘按键方法前需要先导入keys类包。

下面经常使用到的键盘操作:

send_keys(Keys.BACK_SPACE)删除键(BackSpace)

send_keys(Keys.SPACE)空格键(Space)

send_keys(Keys.TAB)制表键(Tab)

send_keys(Keys.ESCAPE)回退键(Esc)

send_keys(Keys.ENTER)回车键(Enter)

send_keys(Keys.CONTROL,'a')全选(Ctrl+A)

send_keys(Keys.CONTROL,'c')复制(Ctrl+C)

send_keys(Keys.CONTROL,'x')剪切(Ctrl+X)

send_keys(Keys.CONTROL,'v')粘贴(Ctrl+V)

send_keys(Keys.F1)键盘F1

……

send_keys(Keys.F12)键盘F12

fromseleniumimportwebdriver#引入 Keys 模块fromselenium.webdriver.common.keysimportKeysdriver=webdriver.Firefox()driver.get("http://www.baidu.com")#输入框输入内容driver.find_element_by_id("kw").send_keys("seleniumm")#删除多输入的一个 mdriver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)#输入空格键+“教程”driver.find_element_by_id("kw").send_keys(Keys.SPACE)driver.find_element_by_id("kw").send_keys(u"教程")#ctrl+a 全选输入框内容driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')#ctrl+x 剪切输入框内容driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'x')#ctrl+v 粘贴内容到输入框driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'v')#通过回车键盘来代替点击操作driver.find_element_by_id("su").send_keys(Keys.ENTER)driver.quit()

4、多frame切换

在web应用中经常会遇到frame嵌套页面的应用,页WebDriver每次只能在一个页面上识别元素,对

于frame嵌套内的页面上的元素,直接定位是定位是定位不到的。这个时候就需要通过switch_to_frame()

方法将当前定位的主体切换了frame里。

参看 hao123首页

#曾经支持的写法#driver.switch_to_frame("iframeu2872032_0")#最新写法driver.switch_to.frame("iframeu2872032_0")#切换到该frame下,然后点击操作,到另一页面。driver.find_element_by_xpath('//*[@id="container"]/div[3]/div/a').click()

#切换到初始framedriver.switch_to.default_content()time.sleep(2)driver.find_element_by_xpath('//*[@id="menus"]/li[2]/a').click()

对于多层frame ,可以使用frame的索引切换

driver.switch_to.frame(3)

如果 iframe没有可用的id 和name属性,还可以使用xpath

#先通过xpath定位到iframexf= driver.find_element_by_xpath('XXXX')#再将定位对象传给switch_to.frame(xf)driver.switch_to.frame(xf)...

5、多窗口切换

有时候需要在不同的窗口切换,从而操作不同的窗口上的元素。但WebDriver提供了switch_to.window()方法可以切换到任意的窗口。

看如下代码

#FileName : Switch_to_frame.py#Author : Adil#DateTime : 2018/3/13 17:49#SoftWare : PyCharmfromseleniumimportwebdriverimporttimedriver=webdriver.Chrome()#driver.implicitly_wait(1)first_url="http://www.hao123.com/"driver.get(first_url)time.sleep(1)#曾经支持的写法#driver.switch_to_frame("iframeu2872032_0")#最新写法driver.switch_to.frame("iframeu2872032_0")#切换到该frame下,然后点击操作,到另一页面。driver.find_element_by_xpath('//*[@id="container"]/div[3]/div/a').click()#获取多窗口句柄get_handles =driver.window_handlesprint(get_handles)#['CDwindow-(79057C598F9424652D25D8405B654717)', 'CDwindow-(99F2157CBA34CE7DAE131D3039561013)']#获取当前窗口句柄get_currentHandle = driver.current_window_handle#CDwindow-(79057C598F9424652D25D8405B654717)print(get_currentHandle)forhandleinget_handles:ifhandle !=get_currentHandle:#最新写法 switch_to.windowdriver.switch_to.window(handle)#曾经支持的写法#driver.switch_to_window(handle)print(driver.current_window_handle)#切换到初始framedriver.switch_to.default_content()time.sleep(2)driver.find_element_by_xpath('//*[@id="menus"]/li[2]/a').click()#关闭当前句柄页driver.close()time.sleep(5)#关闭浏览器driver.quit()6、警告框处理

在WebDriver中处理JavaScript所生成的alert、confirm以及prompt是很简单的。具体做法是使用

switch_to_alert()方法定位到alert/confirm/prompt。然后使用text/accept/dismiss/send_keys按需进行操做。

text:获取文本值

accept() :点击"确认"

dismiss() :点击"取消"或者叉掉对话框

send_keys() :输入文本值 --仅限于 prompt,在 alert 和 confirm 上没有输入

#旧式写法driver.switch_to_alert()#切换到Alter 弹出框上driver.switch_to.alert()#同意点击确认driver.switch_to.alert().accept()#取消操作driver.switch_to.alert().dismiss()#输入文本内容driver.switch_to.alert().send_keys("输入信息!")

7、单选复选框操作

7.1、单选:radio

首先是定位选择框的位置

定位 id,点击图标就可以了 ,即可完成单选的选择。

7.2、复选框:checkbox

勾选单个框,比如勾选 selenium 这个,可以根据它的 id=c1 直接定位到点

击就可以了

全部勾选,可以用到定位一组元素,从上面源码可以看出,复选框的

type=checkbox,这里可以用 xpath 语法: .//*[@type='checkbox']

这里注意,敲黑板做笔记了: find_elements 是不能直接点击的,

它是复数的,所以只能先获取到所有的 checkbox 对象,然后通过 for 循环去一

个个点击操作

判断是否选中:is_selected()

fromseleniumimportwebdriverdriver=webdriver.Firefox()driver.get("file:///C:/Users/Gloria/Desktop/checkbox.html")#没点击操作前,判断选项框状态s = driver.find_element_by_id("boy").is_selected()printsdriver.find_element_by_id("boy").click()#点击后,判断元素是否为选中状态r = driver.find_element_by_id("boy").is_selected()printr#复选框单选driver.find_element_by_id("c1").click()#复选框全选checkboxs = driver.find_elements_by_xpath(".//*[@type='checkbox']")foriincheckboxs:i.click()

8、select下拉框操作

8.1、二次定位

1.定位 select 里的选项有多种方式,这里先介绍一种简单的方法:二次定位

2.基本思路,先定位 select 框,再定位 select 里的选项

#分两步:先定位下拉框,再点击选项s= driver.find_element_by_id('nr')s.find_element_by_xpath("//option[@value='50']").click()

还有另外一种写法也是可以的,把最下面两步合并成为一步:

driver.find_element_by_id("nr").find_element_by_xpath("//option[@value='50']").click()

8.2、直接定位

通过xpath或是css一次性直接定位到 option 上的内容

driver.find.element_by_xpath(".//*[@id='nr']/option[2]").click()

8.3、引入Select模块

select_by_index() :通过索引定位

通过 select 选项的索引来定位选择对应选项(从 0 开始计数),如选择

第三个选项:select_by_index(2)

s = driver.find_element_by_id('nr')Select(s).select_by_index(2)

select_by_value() :通过 value 值定位

通过选项的 value值来定位。每个选项,都有对应的 value 值

第二个选顷对应的 value 值就是"20":select_by_value("20")

s = driver.find_element_by_id('nr')Select(s).select_by_value(20)

sl1 = Select(driver.find_element_by_id('cly_province')) sl1.select_by_value('110000') time.sleep(2)#cly_citysl1= Select(driver.find_element_by_id('cly_city')) sl1.select_by_value('110100') time.sleep(2)#cly_districtsl1 = Select(driver.find_element_by_id('cly_district')) sl1.select_by_value('110105')

select_by_visible_text() :通过文本值定位

Select 模块里面还有一个更加高级的功能,可以直接通过选项的文本内容来

定位。

定位“每页显示 50 条” : select_by_visible_text("每页显示 50 条")

s = driver.find_element_by_id('nr')Select(s).select_by_visible_text("每页显示50条")

deselect_all() :取消所有选项

deselect_by_index() :取消对应 index 选项

deselect_by_value() :取消对应 value 选项

deselect_by_visible_text() :取消对应文本选项

first_selected_option() :返回第一个选项

all_selected_options() :返回所有的选项

9、文件下载和上传

文件下载请参考 http://www.cnblogs.com/BlueSkyyj/p/7526803.html

文件上传介绍两种方法,

请参考:http://www.cnblogs.com/BlueSkyyj/p/7523821.html

http://www.cnblogs.com/BlueSkyyj/p/7523844.html

10、设置元素等待

如今大多数的web应用程序使用AJAX技术。当浏览器在加载页面时,页面内的元素可能并不是同时

被 加 载 完 成 的 , 这 给 元 素 的 定 位 添 加 的 困 难 。 如 果 因 为 在 加 载 某 个 元 素 时 延 迟 而 造 成

ElementNotVisibleException的情况出现,那么就会降低的自动化脚本的稳定性。

WebDriver提供了两种类型的等待:显式等待和隐式等待。

10.1、显示等待

显式等待使WebdDriver等待某个条件成立时继续执行,否则在达到最大时长时抛弃超时异常

(TimeoutException)。

#coding=utf-8fromseleniumimportwebdriverfromselenium.webdriver.common.byimportByfromselenium.webdriver.support.uiimportWebDriverWaitfromselenium.webdriver.supportimportexpected_conditions as ECdriver=webdriver.Firefox()driver.get("http://www.baidu.com")element= WebDriverWait(driver,5,0.5).until(EC.presence_of_element_located((By.ID,"kw")))element.send_keys('selenium')driver.quit()

WebDriverWait()

它是由webdirver提供的等待方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存

在,如果超过设置时间检测不到则抛出异常。具体格式如下:

WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)

driver - WebDriver的驱动程序(Ie,Firefox,Chrome等)

timeout -最长超时时间,默认以秒为单位

poll_frequency -休眠时间的间隔(步长)时间,默认为0.5秒

ignored_exceptions -超时后的异常信息,默认情况下抛NoSuchElementException异常。

until()

WebDriverWait()一般由until()(或until_not())方法配合使用,下面是until()和until_not()方法的说明。

until(method, message=’ ’)

调用该方法提供的驱动程序作为一个参数,直到返回值为Ture。

until_not(method, message=’ ’)

调用该方法提供的驱动程序作为一个参数,直到返回值为False。

Expected Conditions

在本例中,我们在使用expected_conditions类时对其时行了重命名,通过as关键字对其重命名为EC,

并调用presence_of_element_located()判断元素是否存在。

expected_conditions类提供一些预期条件的实现。

title_is用于判断标题是否xx。

title_contains用于判断标题是否包含xx信息。

presence_of_element_located元素是否存在。

visibility_of_element_located元素是否可见。

visibility_of是否可见

presence_of_all_elements_located判断一组元素的是否存在

text_to_be_present_in_element判断元素是否有xx文本信息

text_to_be_present_in_element_value判断元素值是否有xx文本信息

frame_to_be_available_and_switch_to_it表单是否可用,并切换到该表单。

invisibility_of_element_located判断元素是否隐藏

element_to_be_clickable 判断元素是否点击,它处于可见和启动状态

staleness_of 等到一个元素不再是依附于DOM。

element_to_be_selected被选中的元素。

element_located_to_be_selected 一个期望的元素位于被选中。

element_selection_state_to_be 一个期望检查如果给定的元素被选中。

element_located_selection_state_to_be 期望找到一个元素并检查是否选择状态

alert_is_present 预期一个警告信息

除了expected_conditions所提供的预期方法,我们也可以使用前面学过的is_displayed()方法来判断元

素是否可 见

lambad为Python创建匿名函数的关键字。关于Python匿名函数的使用这里不再进行讲解,请参考

Python相关教程。

定义input_为百度输入框,通过is_displayed()判断其是否可见。

10.2、隐式等待

隐式等待是通过一定的时长等待页面所元素加载完成。哪果超出了设置的时长元素还没有被加载测抛

NoSuchElementException异常。WebDriver提供了implicitly_wait()方法来实现隐式等待,默认设置为。它

的用法相对来说要简单的多。

implicitly_wait()默认参数的单位为秒,本例中设置等待时长为10秒,首先这10秒并非一个固定的等

待时间,它并不影响脚本的执行速度。其次,它并不真对页面上的某一元素进行等待,当脚本执行到某个

元素定位时,如果元素可定位那么继续执行,如果元素定位不到,那么它将以轮询的方式不断的判断元素

是否被定位到,假设在第6秒钟定位到元素则继续执行。直接超出设置时长(10秒)还没定位到元素则抛

出异常。

10.3、设置sleep休眠

用sleep()方法,需要说明的是sleep()由Python的time模块提供。

当执行到sleep()方法时会固定的休眠所设置的时长,然后再继续执行。sleep()方法默认参数以秒为单

位,如果设置时长小于1秒,可以用小数点表示,如:sleep(0.5)

11、操作Cookie

有时候我们需要验证浏览器中是否存在某个cookie,因为基于真实的cookie的测试是无法通过白盒和

集成测试完成的。WebDriver提供了操作Cookie的相关方法可以读取、添加和删除cookie信息。

webdriver操作cookie的方法有:

get_cookies()获得所有cookie信息

get_cookie(name)返回有特定name值有cookie信息

add_cookie(cookie_dict)添加cookie,必须有name和value值

delete_cookie(name)删除特定(部分)的cookie信息

delete_all_cookies()删除所有cookie信息

下面通过get_cookies()来获取当前浏览器的cookie信息

下面贴上代码

#FileName : handleCookie.py#Author : Adil#DateTime : 2018/3/17 19:38#SoftWare : PyCharmfromseleniumimportwebdriverimporttimeurl='https://www.yiyao.cc/'driver=webdriver.Chrome()driver.get(url)driver.maximize_window()#获取指定cookie的值#cookie = driver.get_cookie()cookies=driver.get_cookies()print("登录前!")print("cookies:")print(cookies)driver.find_element_by_id("new-username").clear()driver.find_element_by_id("new-username").send_keys("username")driver.implicitly_wait(5)driver.find_element_by_id("new-password").clear()driver.find_element_by_id("new-password").send_keys("password")driver.find_element_by_id('home-right-login').click()driver.implicitly_wait(5)#加一个休眠,这样得到的cookie 才是登录后的cookie,否则可能打印的还是登录前的cookietime.sleep(5)print("登录后!")cookiesAfter=driver.get_cookies()print("cookiesAfter:")print(cookiesAfter)print("cookie")print(driver.get_cookie("domain"))driver.add_cookie({'name':'yangyaojun','value':"yangpass"})#再次查看 cookies,打印出的信息是包含上面添加的内容的print(driver.get_cookies())driver.quit()

delete_cookie() 和 delete_all_cookies()的使用也很简单,前者通过那么删除一个特定的cookie信息,后者直接删除浏览器中所有的cookies()信息。

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180318G0ZSQH00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券