三、常用Web Driver API
1、元素定位
(1)常规定位
(2)Xpath定位
- Xpath规则
- 其他
-
- text(): 获取节点文本
- [@xx]:属性匹配
- @xx:属性获取
- [contains(@xx)]:多属性匹配
- [contains(@xx) and @xxx]:多属性匹配
- 按节点选择:输入数字、last()、position()
- 节点轴选择:子元素、兄弟元素、父元素、祖先元素
- Selenium中定位
(3)CSS选择器定位
- 语法
- 定位
(4)Xpath与CSS对比
(5)By定位
统一调用find_element()方法,通过By声明定位方法
2、控制浏览器
3、WebElement功能及方法,与页面元素的交互
5、鼠标事件
ActionChains类提供了鼠标操作的常用方法: 需引入ActionChains(动作链)模块: 调用ActionChains类方法时,不会立即执行,而是将所有操作都存放在一个队列里,当调用perform()方法时,队列里的操作会依次执行
6、键盘事件
Keys()类提供
# 需引入Keys模块
driver.find_element_by_id("kw").send_keys("seleniumm")
sleep(3)
# Backspace
driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)
sleep(3)
#space
driver.find_element_by_id("kw").send_keys(Keys.SPACE)
sleep(3)
driver.find_element_by_id("kw").send_keys("aaa")
sleep(3)
# ctrl+a
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'a')
sleep(3)
# ctrl+x
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'x')
sleep(3)
# ctrl+v
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'v')
sleep(3)
driver.find_element_by_id("su").send_keys(Keys.ENTER)
sleep(3)
7、设置元素等待
(1)、显示等待:等待某个条件成立时继续执行,否则在达到最大时长时抛出超时异常(TimeoutException)
- WebDriverWait类:是web Driver提供的等待方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常;一般与until()或until_not()配合使用。
- 格式:WebDriverWait(driver, timeout, poll_frequency=0.5, ignore_exceptions=None)
- 浏览器驱动;最长超时时间,默认单位秒;检测的间隔(步长)时间,默认0.5s;超时后的异常信息,默认抛出NoSuchElementException异常;
- expected_codition类提供预期条件判断方法
- 自定义预期条件
(2)、隐式等待:通过一定的时长等待页面某元素加载完成,超出时长元素没有定位到则抛出异常。
- 为Webdriver中的完整的一个测试用例或一组测试的同步提供通用方法。
- 设置隐式等待后,作用于整个生命周期或 一次完整测试执行期间,且Webdriver会使其对所有测试步骤中包含整个页面元素的查找都有效,除非设置为0;
- Webdriver会在一定时间内持续检测和搜寻DOM
- implicitly_wait()方法,默认设置为0
- 设置的时间不是一个固定时间,并不影响脚本的执行速度;
- 并不针对页面上的某一元素进行等待。当脚本执行到某个元素定位时,如果元素可以定位,则继续执行;如果元素定位不到,则将以轮询的方式不断地判断元素是否被定位到。若超出设置时长,则抛出异常。
# 设置隐式等待10s
driver.implicitly_wait(10)
try:
print(ctime())
driver.find_element_by_id("kw22").send_keys('selenium')
except NoSuchElementException as e:
print(e)
finally:
print(ctime())
driver.quit()
(3)强制等待:time.sleep()
8、定位一组元素
9、多表单切换
10、多窗口切换
- switch_to.window()
# 获得百度搜索窗口句柄
search_windows = driver.current_window_handle
driver.find_elements_by_link_text('登录').click()
driver.find_elements_by_link_text('立即注册').click()
# 获得当前所有打开的窗口的句柄
all_handles = driver.window_handles
#进入注册窗口
for handle in all_handles:
if handle != search_windows:
driver.switch_to.window(handle)
print('now register window!')
driver.find_element_by_name("account").send_keys('username')
driver.find_element_by_name("password").send_keys('password')
time.sleep(2)
11、警告框处理
Alter类操控JSP警告
alert_is_present()判断是否存在Alerts
12、上传下载文件
1、上传
(1)input标签
直接send_keys
(2)非input性上传
- autoIT,借助外力;
(1)通过autoIT的获取对象并编辑脚本:
(2)通过Aut2Exe工具将脚本转成exe文件(upfile.exe)
(3)验证,通过命令行打开网页上传弹框,在cmd中执行该脚本
(4)用Python用os模块调用该文件
- Python pywin32库,识别对话句柄进而操作
- SendKeys库;
-
- pip install SendKeys---Py2.7
- 替代PyUserInput---https://www.cnblogs.com/yoyoketang/p/8043814.html
- keybd_event,与SendKeys类型,不过是模拟按键,ctrl+a..
2、多文件上传
3、下载
(1)Firefox文件下载
对于Firefox,需要设置其Profile:
注: Firefox需要针对每种文件类型进行设置,这里需要查询对应文件的MIME类型,可以用以下链接进行查询:MIME 参考手册
- browser.download.dir:指定下载路径;
- browser.download.folderList:设置成 2 表示使用自定义下载路径;设置成 0 表示下载到桌面;设置成 1 表示下载到默认路径;
- browser.download.manager.showWhenStarting:在开始下载时是否显示下载管理器;
- browser.helperApps.neverAsk.saveToDisk:对所给出文件类型不再弹出框进行询问。
(2)Chrome文件下载
Chrome浏览器类似,设置其options:
- download.default_directory:设置下载路径
- profile.default_content_settings.popups:设置为 0 禁止弹出窗口
13、cookie操作
driver.get("https://www.youdao.com";)
cookie = driver.get_cookies()
print(cookie)
driver.add_cookie({'name': 'key-aaaaa', 'value': 'value-aaaa'})
for cookie in driver.get_cookies():
print("%s -> %s" %(cookie['name'], cookie['value']))
# Selenium添加访问cookie实现自动登录
#(1) 登录并保存cookie
# 前面部分代码用于填写登录信息并登录
# 获取cookie并通过json模块将dict转化成str
dictCookies = self.browser.get_cookies()
jsonCookies = json.dumps(dictCookies)
#登录完成后,将cookie保存到本地文件
with open('cookies.json', 'w') as f:
f.write(jsonCookies)
#(2) 读取cookie实现免登录访问
# 初次建立连接,随后方可修改cookie
self.browser.get('http://xxxx.com';)
# 删除第一次建立连接时的cookie
self.browser.delete_all_cookies()
# 读取登录时存储到本地的cookie
with open('cookies.json', 'r', encoding='utf-8') as f:
listCookies = json.loads(f.read())
for cookie in listCookies:
self.browser.add_cookie({
'name': cookie['name'],
'value': cookie['value'],
'path': '/',
'expires': None
})
# 再次访问页面,便可实现免登陆访问
self.browser.get('http://xxx.com';)
14、调用Javascript
# 操作滚动条
# execute_script()
# (1) 纵向滑动
js = "window.scrollTo(100, 450);"
driver.execute_script(js)
# (2) 横向滑动
#移动到最右边
js5 = "window.scrollTo(document.body.scrollWidth,0)"
#移动到最左边
js6 = "window.scrollTo(0,0)"
#移动到向右移动200像素
js7 = "window.scrollTo(200,0)"
# (3)操作内嵌滚动条
# 内嵌滚动条,一般嵌在一个iframe 里面,先切到要操作滚动条所在的iframe里面即可
driver.get("http://sahitest.com/demo/iframesTest.htm";)
sleep(2)
driver.switch_to.frame(1)
js5 = "window.scrollTo(0,200)"
driver.execute_script(js5) #向下移动200像素
#(4)总结
# 1)使用window.scrollTo(x,y) 这一语句,可以实现所有的纵向或横向滑动滚动条。其中x为横坐标,y为纵坐标,想纵向滚动200像素,就window.scrollTo(0,200)
# 2)获取当前窗口的高度和宽度
document.body.scrollWidth
document.body.scrollHeight
# 3)滑动到指定元素位置
arguments[0].scrollIntoView() ,arguments[0] 是指第一个传参
# 二 修改元素属性
15、窗口截图
# get_screenshot_as_file()
# 截取当前窗口并指定截图图片的保存位置
driver.get_screenshot_as_file("C:\\Users\\sogaa001\\Desktop\\baidu_test.jgp")
16、下拉框
(1) 使用Select类
17、操作输入框
ele = driver.find_element_by_id('kw')
#获得输入框的值
ele.get_property('value')
#获得name属性值
ele.get_attribute('name')
#输入框是否可见
ele.is_displayed()
#输入框是否可用
ele.is_enabled()
#输入框是否被选中
ele.is_selected()
# 操作表格
# (1) 取某个单元格中的值像普通元素一样定位
# (2) 打印表格所有值
思路:
1、先定位页面中表格对象元素
2、在该表格中,通过tag name = ‘tr’ 找所有行
3、在第一行中,通过tag name = ‘td’ 找所有列
driver = webdriver.Chrome()
driver.get('http://sahitest.com/demo/tableTest.htm';)
table = driver.find_element_by_xpath('/html/body/table[1]')
rows = table.find_elements_by_tag_name('tr')
cols = rows[0].find_elements_by_tag_name('td')
for i in range(len(rows)):
for j in range(len(cols)):
cell = rows[i].find_elements_by_tag_name('td')[j]
print(cell.text)
18、操作日期时间控件
# js = "document.getElementById('c-date1').removeAttribute('readonly')" # 1.原生js,移除属性
# js = "$('input[id=c-date1]').removeAttr('readonly')" # 2.jQuery,移除属性
# js = "$('input[id=c-date1]').attr('readonly',false)" # 3.jQuery,设置为false
js = "$('input[id=c-date1]').attr('readonly','')" # 4.jQuery,设置为空(同3)
19、Selenium之定制Chrome的选项(Options)
- chromeoptions
chromeoptions 是一个方便控制 chrome 启动时属性的类。通过 selenium 的源码,可以看到,chromeoptions 主要提供如下的功能:
(1)设置 chrome 二进制文件位置 (binary_location)
(2)添加启动参数 (add_argument)
(3)添加扩展应用 (add_extension, add_encoded_extension)
(4)添加实验性质的设置参数 (add_experimental_option)
(5)设置调试器地址 (debugger_address)
- 定制启动选项
(1)添加chrome启动参数
# 启动时设置默认语言为中文 UTF-8
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument('lang=zh_CN.UTF-8')
driver = webdriver.Chrome(chrome_options = options)
最常用的应用场景是设置user-agent以用来模拟移动设备,比如模拟 iphone6
options.add_argument('user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1"')
(2)修改chrome设置
# 禁止图片加载
from selenium import webdriver
options = webdriver.ChromeOptions()
prefs = {
'profile.default_content_setting_values' : {
'images' : 2
}
}
options.add_experimental_option('prefs',prefs)
driver = webdriver.Chrome(chrome_options = options)
driver.get("http://www.baidu.com/";)
(3)添加扩展应用
from selenium import webdriver
options = webdriver.ChromeOptions()
extension_path = '/extension/path'
options.add_extension(extension_path)
driver = webdriver.Chrome(chrome_options = options)
(4)附赠添加代理方法
from selenium import webdriver
PROXY = "proxy_host:proxy:port"
options = webdriver.ChromeOptions()
desired_capabilities = options.to_capabilities()
desired_capabilities['proxy'] = {
"httpProxy":PROXY,
"ftpProxy":PROXY,
"sslProxy":PROXY,
"noProxy":None,
"proxyType":"MANUAL",
"class":"org.openqa.selenium.Proxy",
"autodetect":False
}
driver = webdriver.Chrome(desired_capabilities = desired_capabilities)
(5)启动浏览器,最大化
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--start-maximized")
driver = webdriver.Chrome(chrome_options=options)
(6)指定driver地址
from selenium import webdriver
driver = webdriver.Chrome(executable_path='..drivers\chromedriver.exe')
这个地方的executable_path,可以是一个相对路径或一个绝对路径
20、Selenium三种断言以及异常类型