selenium学习笔记
第1节课:selenium简介
web 自动化测试的2种方式
模拟整个客户端通过http协议向服务器发送请求
一种是以服务器为测试对象的自动化测试,主要是指性能测试
一种是以客户端为测试对象的自动化测试,主要是指功能的自动化测试。
selenium 主要是通过模拟人的操作进行基于UI层面的自动化测试
selenium 是自动化浏览器的工具包
可以用于各个方面,web 测试自动化、日常的web操作
从web 应用的源头(浏览器)驱动应用
使用范围非常广泛
控制成本、提高效率
selenium2、3 工具包构成:
web Driver 是selenium 的核心。
通过浏览器驱动控制浏览器,浏览器驱动都是浏览器厂商自己开发的。
把自动化命令通过web driver接口规范 发送给浏览器驱动,驱动并操作浏览器。
构造http请求消息通过selenium提供 的客户端库发送消息给浏览器驱动
工作原理:
selenium IDE :通过录制回放的方式把浏览器操作录制下来,功能有限,对于复杂的
业务无法支持。
selenium Grid : 可以用来在多台机器上同时执行selenium自动化测试
主要表现:
执行的测试用例非常多
其中某些测试非常耗时
通过定位元素进行操作
HTML:
HTML元素是用标签表示的。
尖括号包括元素名称,形成了HTML标签
HTML标签通常是成对出现的。
标签对中的第一个标签是开始标签,第二个标签是结束标签
有的标签里面可以包含其他标签,如HTML、head、body等
以<!docthpe>声明开头
以开始,以结尾
可见部分内容在和之间
HTML 元素的属性:
HTML 链接:
由标签定义,链接地址在href 属性中指定
属性总是在HTML 元素的开始标签中规定
属性总是以名称和值对的形式出现
一个元素可以有很多的属性,属性用来描述元素的特征
img是图片,图片地址是src开头的
table:表格, 每一格的标签是td表示的
div :存放其他元素,规划区域,布局使用的。
p:就是文本的内容,也可以是段落的内容
id是非常特殊的属性,它是用来唯一标志一个元素
标准元素,都有规定的合法属性。
一些常用的元素
div 元素;用来放其他元素的。用来布局的
第2节课:web driver自动化初次接触
selenium2 与3 的区别基本很小,区别在于webdrive与浏览器进行通信这块,对于我们调用客户端库
区别不大。
通过 pip install selenium -U 更新安装
pip install selenium
选择元素
Webdriver:操作整个浏览器和当前整个页面
当前页面上的选择符合查找条件的对象
打开网址,回退、前进、刷新网页
获取、改变浏览器窗口大小、关闭浏览器,截屏
获取、设置cookies
WebElement:操作和对应web元素
当前web元素的所有子元素里面符合查找条件的对象
操作该web元素,比如:
1 点击元素
2 输入字符
3 获取元素坐标、尺寸、文本内容、其它的属性信息
通过id选择元素的另一种写法:
from selenium.webdriver.common.by import By
forcast_weather = driver.find_element(by=By.ID,value=“forecastID”)
print(forcast_weather.text)
获取元素信息
text属性 显示该元素在web页面显示出来的文本内容
get.attribute方法:
ele.get_attribute(‘属性名称’) 获取某个属性的值
ele.get_attribute(‘outerHTML’) 该元素对应html源代码
ele.get_attribute(‘innerHTML’) 该元素的内部部分的html源代码
ele.get_attribute(‘outerText’)
ele.get_attribute(‘innerText’)
BeautifulSoup4
BS是可以从HTML或XML文件中提取数据的库
Selenium可以用来远程获取数据
有的时候,感觉用Selenium获取某些元素数据不太方便
可以将其父节点的html获取回来,利用BS在本地做分析
我们可以将它和Selenium两种技术融合试用,达到我们的目的
安装
pip install beautifulsoup4/pip install beautifulsoup4 -i https://pypi.douban.com/simple/
pip install html5lib(解析器)
soup = BeautifuleSoup(html_doc,‘html5lib’)
print(soup.title.string)
print(soup.title.get_text()) #获取子节点也可以
print(soup.div.get_text(’|’)) #按竖线分割开
print(soup.title.parent) #获取当前节点的父节点
print(tag)
print(dd)
print(soup.div[‘id’]) #获取属性的名字
print(soup.div.get(‘id’)) #同样可以获取属性的名字
print(soup.find_all(‘a’)[2]) #获取第二个元素
通过name选择元素
driver.find_element_by_name(‘值’) 返回的是第一个对象
driver.find_elements_by_name(‘值’) 返回的是
通过class(类型)选择元素:
通常是复数
driver.find_element_by_class_name(‘值’)
通过tag名选择元素
tag名如果是唯一的,可以根据tag名定位
driver.find_element_by_tag_name(‘值’)
通过链接文本选择元素
对于链接,可以通过链接文本的内容
转到百度
可以这样选择ele = driver.find_element_by_link_text(u’转到百度’)
通过选择部分文本知道找到该链接的元素:
ele = driver.find_element_by_partial_link_text(u’百度’) #u是对python2 而言,对python3 可以不加
通过partial link 定位 #文本信息是唯一的即可。
例:
find_element_by_partial_link_text(‘文本信息’)
通过逻辑运算符定位
find_elements_by_xpath(’//input[@id=‘kw’ and @class=‘su’]’)
选择一个元素的时候,设定一个最大等待时间,
那么会周期性的每隔0.5s重新寻找该元素,直到该元素找到
或者超出最大等待时长,会报错
隐式等待
全局的设定
driver.implicitly_wait(10) ,只针对find系列的方法有效
显示等待:
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Firefox()
driver.implicitly_wait(10) # 隐性等待和显性等待可以同时用,但要注意:等待的最长时间取两者之中的大者
driver.get(‘https://huilansame.github.io’)
locator = (By.LINK_TEXT, ‘CSDN’)
简单做法:
如果某一个操作需要长时间加载,可以先改变全局等待时间
例如:
driver.implicitly_wait(60)
这种方式就是如果找不到元素,后面的将不再执行。解决办法是:
try:
wo = driver.find_element_by_id('forecastID')
if ele.text.xxxxxxxxxxxx:
print 通过
else:
print 不通过
except:
print(exception happened)
finally:
driver.implicitly_wait(10)
ID名称不规则的可能会变动,判断方法为刷新页面后是否不变,如果不变则可以用
frame处理: 内联框架
切换到frame里面:
driver.switch_to.frame(‘kw’) #括号里是国中之国的name or id or 索引值
frame 元素的name属性或id属性
索引值(从0开始):0 第一个就是0
frame 所对应的webelement :driver.find_element_by_tag_name(‘iframe’)
切换回主HTML里面:
driver.switch_to.default.content()
注意那些会变的ID:
switch_to_frame() 默认可以直接取表单的id 或name 属性进行切换
#切换到iframe(id = “if”)
driver.switch_to_frame(“if”)
#id = “if”
driver.switch_to_frame(“if”)
#name = “nf”
driver.switch_to_frame(“nf”)
那么如果iframe 没有可用的id 和name 可以通过下面的方式进行定位:
#先通过xpth 定位到iframe
xf = driver.find_element_by_xpath(’//*[@class=“if”]’)
#再将定位对象传给switch_to_frame()方法
driver.switch_to_frame(xf)
如果完成了在当前表单上的操作可以通过switch_to_default_content()方法返回到上一层单。该方法不用指定某个表单的返回,默认对应与它最近的switch_to_frame()方法
如果有多个frame ,可以直接用frame的名字或ID
css选择器
根据tag名
p{color:red;}
根据id
#food{color:red;}
根据class
.vegetable {color:red;}
class = ‘vegetable good’ #代表该元素有两个类型或者两个class属性,那么唯一选中这种的选择方法是:.vegetable.good(中间不可有空格)
一般ID不和tag和class属性组合,因为是唯一的
根据tag名和class组合写(如果多个)
span.vegetable {color:red;}
span .vegetable 和span.vegetable 是不同的意思,前者表示在span 标签中选择vegetable ,否则是在span后代中选择.vegetable
后代选择器:
选择元素内部的元素
语法:
选择s1元素里面所有的s2元素
可以是直接子节点,也可以不是
比如:
#choose_car option
footer p
可以是很多级
ul ol li em {color:blue;}
子元素(child)选择器
后代选择器不同:#choose_car option
比如子元素选择如下:
choose_car > option
footer > p
可以是很多级
ul > ol > li >em
同时选择符合两种要求的元素:
用逗号隔开,例如:
footer > button,span
button,span
#food,.cheese
#food,.cheese即表示id是food,class属性是cheese的元素
#food > span,p 即表示ID是food的span和所有p的元素,逗号分隔的前后属于两部分
#food > span,#food > p 即表示id是food下面的所有span和p元素
通配符:
#food > * 即表示id是food的下面的所有子元素
兄弟节点(后面的节点)紧跟在后面的一个元素
比如:#food + div #找的还是div这个元素,但是紧跟在#food后面的元素
如果不是紧跟着的兄弟节点可以用:
food ~ div
根据元素的属性及属性值来选择元素:
*[style] #选择所有有style属性的元素
p[style=‘red’] #选择所有style=red的p tag元素 视情况决定要不要加引号
p[spec=‘len2 len3’] #与class不同,该处表示选择spec='len2 len3’的p tag元素
p[spec=‘len2’] #选择只要spec2包含len2属性的p元素都可以选中
p[spec^=‘len2’] #表示spec是len2开头的p元素
p[spec$=‘len2’] #表示spec是以len2结尾的p元素
p[spec=‘len2’][name=‘p1’] #表示同时有多个属性的p元素
其他css常用的选择元素方法:
p:nth-child(2) #不管是什么类型,选择p是它父节点的第二个元素的元素
p:nth-last-child(1) #选择p是它父节点的倒数第一个元素
p:nth-of-type(1) #选择必须是p类型里的第一个p元素
#food >:not§ #选择非p的元素,在food里面
确定该元素是否是唯一的,可以在console里输入css表达式:
ele.clear() #用clear 方法清除该元素里面字符串
ele.get_attribute(value) #获取input1元素里面输入的文本内容
单选框:
type类型是radio
click方法选择
不管原来该元素是否选中,直接点击该元素没有问题
都可以确保该单选框选中
勾选框
type类型是 CheckBox
首先获取选择的状态
input1=driver.find_element_by_xpath(’//input[@value=“cv1”]’)
slect = input1.is_selected()
然后if slect
print(‘已经选中’)
else:
print(‘选中xx’)
input1.click()
复选框:
type类型是select
from selenium.webdriver.support.ui import Select
导入select包
获得相应的WebElement
select = Select(driver.find_element_by_id(“multi”))
先去选择所有的选项
select.deselect_all()
#再选择需要选择的
select.select_by_visible_text(“雅阁”)
如果是单一的选择框可以直接选择:
获得相应的WebElement
select = Select(driver.find_element_by_id(“single”))
select.select_by_visible_text(“男”)
xpath选择
xpath 是W3C定义的用来在xml文档中选择节点的语言
主流浏览器也支持XPATH语法
移动端的应用只能用xpath,不支持css
主流浏览器(自己开发内核的)也支持xpath
对于浏览器原生支持xpath,selenium尽量使用原生的xpath实现,有些浏览器也支持通过xpath来访问
xpath的语法看起来非常像电脑文件系统的路径 从根节点开始
/html/div/body 即表示选中的是html下的子节点div下的子节点body
根节点:
根节点用/表示
对应整个HTML
/html/body/div 一级一级
// 表示从当前路径选择 所有后代元素 也就是相对路径的意思
//name[@id=‘xiaoxiao’]
$$(’’)
$x #console xpath写法
//div/p #表示p是div的直接子节点
//div//p #表示p不是div的直接子节点
通配符
和css一样,xpath
//div/*
根据属性进行选择
//*[@style] #选择所有具有style属性的元素
//name[@id=‘xiaoxiao’]
注意:css中如果是属性值,如果没有空格可以不加引号
但是,xpath必须要引号,单引号和双引号都可以
根据id、class选择
//div[@id=‘food’]
//div[@class=‘chess’]
子元素的选择
选择属于其父元素的第N个某个类型的子元素
//p[2] 等价于 p:nth-of-type(2)
//[@id=‘food’]/p[1] 等价于 #food >p:nth-of-type(1)
//[@id=‘food’]/*[1] =#food >p:nth-chind(3)
选择属于其父元素的倒数第N个某个类型的子元素
//span[last()-1] 属于其父元素的倒数第二个span
//[@id=‘food’]/span[last()]
//[last()-1]
//[last()] #表示最后一个元素
//[last()-1] #表示倒数第2个元素
//p[last()-2] #表示倒数第3个元素 等价于p:nth-last-of-type(3 )
子元素选择
选择属于其父元素的第N个子元素
//[2]等价于//[position()=2] 等价于*:nth-chind(2)
//[@id=‘food’]/[position()=3] #id是food元素的子元素的等于3 position()是位置函数
//[@id=‘food’]/[position()❤️] #id是food元素的子元素的前2个
//[@id=‘food’]/[position()<=3] #id是food元素的子元素的前3个
选择属于其父元素的倒数第N个的子元素
//[id=‘food’]/[last()-1]等价于
//[@id=‘food’]/[position()=last()-1] #position()相当于下标
#id是food元素的子元素的倒数4个
倒数一定用last()
组选择
用多个表达式一起
css用,分开
比如p,button
xpath用|分开
//p|//button
等价于p,button
#food ~div
等价
//*[@id=‘food’]/following-sibiling::div #后面的所有的兄弟节点为div的
//*[@id=‘food’]/preceding-sibiling::div #前面的所有的div节点
#food+div
等价
//[@id=‘food’]/following-sibiling::[1]
选择父节点:
//[@id=‘food’]/… #上一层节点
//[@id=‘food’]/…/… #上上层节点
//span[@price>50] #比较大小
在对象里面查找对象,需要在在前面加.例如:要找id是food下面的子节点,假如已经找到了id = food的元素
.//p
第11节课:selenium 实用技巧
webDriver对象的一些方法
driver.implicitly_wait(10) 只对find等方法有效
获取当前窗口的title
driver.title
获取当前窗口的地址
driver.current_url
随着用户的操作,title和current url会变化,比如在百度中输入关键字后再获取的title和url又会产生变化,注意title的变化,打印的时候可能还是上一个title,主要要等待一会儿
截屏:
driver.get_screenshot_as_file(‘ssl.png’) 针对打开某个网页后截屏
针对元素的截图目前还没有支持
针对新功能可以搜索、或者猜想
切换窗口
driver.window_handles当前所有的窗口是一个列表
driver.switch_to_window(handle)切换至某个窗口,handle相当于一个ID
driver.current_window_handle 当前的窗口
新打开标签页和新打开窗口对自动化测试没有区别
在切换之前保存原来窗口:
#保存主窗口handle
mainWindow = driver.current_window_handle
关闭窗口
drvier.close()只关闭当前窗口
driver.quit()整个浏览器包括驱动都关闭
检查所有打开窗口中有title是百度的 :
for handle in driver.window_handles:
# 切换到新窗口
driver.switch_to.window(handle)
# 检查是否是我们要进入的window
if ‘百度’ in driver.title:
break
driver.quit() #关闭所有窗口
driver.close() #关闭当前窗口
弹出对话框 #它不是HTML的一部分,而是浏览器内置的内容
alert (单一按钮)
对话框一般来说有三种
alert 确定
confirm 确定或者取消
prompt 输入内容后确定或者取消
操作方法
driver.switch_to.alert.accept()#表示点击ok
操作方法:
获取弹窗上面的文本信息:
driver.find_element_by_id(‘h’).click()
print(driver.switch_to.alert.text)
confirm #有ok和取消按钮
driver.switch_to.alert.accept() #点击ok
driver.switch_to.alert.dismiss() #点击取消
prompt #输入文本信息
driver.switch_to.alert.send.keys(‘你好’)
实用技巧
易消失元素的查看技巧
鼠标移到该元素上面才会出现,鼠标移开就消失,在浏览器console中执行:
setTimeout(function(){debugger},5000)
5秒后开始查看
上传文件的技巧:
上传文件(windows平台,操作自动化的时候不能干别的事情,因为是定位当前屏幕的)
先导入库:
import win32com.client
固定写法
shell=win32com.client.Dispatch(“WScript.Shell”)
上传的文件路径
shell.SendKeys(r’D:\TTT\untitled\samples_selenium\wd\lesson06\cc.png’+’\r\n’)
另一种上传方法:
driver.find_element_by_class_name(‘upload-pic’).send_keys(r’C:\Users\jack\Desktop\cc.png’)
上传过程中不要动鼠标
文件下载路径配置:基于Chrome
options = webdriver.ChromeOptions()
options.add_experimental_option(“prefs”, {
“download.default_directory”: r"C:\Users\jack\Desktop\file",
“download.prompt_for_download”: False,
“download.directory_upgrade”: True,
"safebrowsing.enabled
": True
})
driver = webdriver.Chrome(chrome_options=options,executable_path=r’d:\tools\webdriver\chromedriver.exe’)
联想框 保持不动可以点击鼠标右键选择respect
自己整理的:
第1节课:selenium简介
web 自动化测试的2种方式
模拟整个客户端通过http协议向服务器发送请求
一种是以服务器为测试对象的自动化测试,主要是指性能测试
一种是以客户端为测试对象的自动化测试,主要是指功能的自动化测试。
selenium 主要是通过模拟人的操作进行基于UI层面的自动化测试
selenium 是自动化浏览器的工具包
可以用于各个方面,web 测试自动化、日常的web操作
从web 应用的源头(浏览器)驱动应用
使用范围非常广泛
控制成本、提高效率
selenium2、3 工具包构成:
web Driver 是selenium 的核心。
通过浏览器驱动控制浏览器,浏览器驱动都是浏览器厂商自己开发的。
把自动化命令通过web driver接口规范 发送给浏览器驱动,驱动并操作浏览器。
构造http请求消息通过selenium提供 的客户端库发送消息给浏览器驱动
工作原理:
selenium IDE :通过录制回放的方式把浏览器操作录制下来,功能有限,对于复杂的
业务无法支持。
selenium Grid : 可以用来在多台机器上同时执行selenium自动化测试
主要表现:
执行的测试用例非常多
其中某些测试非常耗时
通过定位元素进行操作
HTML:
HTML元素是用标签表示的。
尖括号包括元素名称,形成了HTML标签
HTML标签通常是成对出现的。
标签对中的第一个标签是开始标签,第二个标签是结束标签
有的标签里面可以包含其他标签,如HTML、head、body等
以<!docthpe>声明开头
以开始,以结尾
可见部分内容在和之间
HTML 元素的属性:
HTML 链接:
由标签定义,链接地址在href 属性中指定
属性总是在HTML 元素的开始标签中规定
属性总是以名称和值对的形式出现
一个元素可以有很多的属性,属性用来描述元素的特征
img是图片,图片地址是src开头的
table:表格, 每一格的标签是td表示的
div :存放其他元素,规划区域,布局使用的。
p:就是文本的内容,也可以是段落的内容
id是非常特殊的属性,它是用来唯一标志一个元素
标准元素,都有规定的合法属性。
一些常用的元素
div 元素;用来放其他元素的。用来布局的
第2节课:web driver自动化初次接触
selenium2 与3 的区别基本很小,区别在于webdrive与浏览器进行通信这块,对于我们调用客户端库
区别不大。
通过 pip install selenium -U 更新安装
pip install selenium
第3、4节课:web元素的选择和操作
selenium 主要是选择界面元素,操作界面元素
webdriver 操作整个浏览器和当前整个页面
打开网址、回退、前进、刷新网页等等
webElement :操作和对应web元素
当前web元素的所有子元素里面符合查找条件的对象。
比如,点击元素、输入字符
获取元素坐标、尺寸,文本内容,其他的属性信息。
通过id选择元素
效率最高、最简单
ele = driver.find_element_by_id(‘KW’)
或
form selenium.webdriver.common.by import_By
element = driver.find_element(by=By.ID,value = ‘kw’)
捕获异常:
先导入异常类
在声明该异常
例如:
from selenium.common.exceptions import NoSuchElementException
try:
ele = driver.find_element_by_name(“button4”)
except selenium.common.exceptions.NoSuchElementException:
print(‘不存在’)
获取元素信息:
text 属性: 显示该元素在web页面显示出来的文本内容
get.attribute方法,先获取id,再获取属性
某个属性的值
ele.get_attribute(‘href’)
该元素对应的html源代码
ele.get_attribute(‘outerHTML’)
该元素的内容部分的html源代码
ele.get_attribute(‘innerHTML’)
BeautifuSoup4
bs 是可以从HTML或xml 文件中提取数据的库
selenium 可以用远程获取数据,利用bs在本地做分析
安装pip install beautifulsoup4
pip install html5lib 兼容性HTML更强
参考文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/
例子:
with open(‘bs1.html’,encoding=‘utf8’) as f:
html_doc = f.read()
导入 BeautifulSoup
from bs4 import BeautifulSoup
指定用html5lib来解析html文档
soup = BeautifulSoup(html_doc, “html5lib”)
print(soup.title.string)
print(soup.title.get_text()) #获取子节点也可以
print(soup.div.get_text(’|’)) #按竖线分割开
print(soup.title.parent) #获取当前节点的父节点
print(tag)
print(dd)
print(soup.div[‘id’]) #获取属性的名字
print(soup.div.get(‘id’)) #同样可以获取属性的名字
print(soup.find_all(‘a’)[2]) #获取第二个元素
通过name 选择元素
如果有多个,将返回第一个找到的元素
ele = driver.find_element_by_name(‘cheese’)
或者
from selenium.webdriver.common.by import By
cheese = driver.find_element(By.NAME,‘cheese’)
返回所有的元素
cheese = driver.find_elements_by_name(‘cheese’)
#返回的是一个列表,一一对应显示,如果找不到,返回一个
空list,不报异常
通过class选择元素
一个web元素
cheese = driver.find_elements_by_class_name(‘cheese’)
通过tag选择元素
假设如下片段:
fram = driver.find_element_by_tag_name(‘iframe’)
通过链接文本选择元素
对于链接,可以通过链接文本的内容
转到百度
可以这样选择ele = driver.find_element_by_link_text(u’转到百度’)
通过选择部分文本知道找到该链接的元素:
ele = driver.find_element_by_partial_link_text(u’百度’) #u是对python2 而言,对python3 可以不加
通过partial link 定位 #文本信息是唯一的即可。
例:
find_element_by_partial_link_text(‘文本信息’)
通过逻辑运算符定位
find_elements_by_xpath(’//input[@id=‘kw’ and @class=‘su’]’)
driver.forward() #浏览器前进
driver.back() #浏览器后退
控制窗口大小
driver.set_window_size(420,800)
窗口最大化
driver.maximize_window()
刷新页面
driver.refresh()
提交表单是可以使用submit()
获取元素的大小
size = driver.find_element_by_name(“tj_trnews”).size
获取元素的类型
s = driver.find_element_by_name(“tj_trnews”).get_attribute(‘type’)
获取元素时候可见
size = driver.find_element_by_name(“tj_trnews”).is_displayed()
from selenium.webdriver.common.action_chains import ActionChains
鼠标右击操作
size = driver.find_element_by_name(“tj_trnews”)
ActionChains(driver).context_click(size).perform()
鼠标悬停操作
shop=driver.find_element_by_name(‘tj_briicon’)
ActionChains(driver).move_to_element(shop).perform()
鼠标双击操作
q = driver.find_element_by_css_selector(".rtit.r1").click()
ActionChains(driver).double_click(q).perform()
鼠标拖动操作
ActionChains(driver).drag_and_drop(size,shop).perform() #size 是源元素,shop是目的元素
先导入keys 类
from selenium.webdriver.common.keys import Keys
删除一个字符
driver.find_element_by_id(‘kw’).send_keys(Keys.BACK_SPACE)
输入空格
ele = driver.find_element_by_id(‘kw’).send_keys(Keys.SPACE)
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(‘kw’).send_keys(Keys.ENTER)
获得title
driver.title
获得页面url
driver.current_url
第5、6节课:selenium等待元素出现和CSS选择器
选择一个元素的时候,设定一个最大等待时间,
那么会周期性的每隔0.5s重新寻找该元素,直到该元素找到
或者超出最大等待时长,会报错
隐式等待
全局的设定
driver.implicitly_wait(10) ,只针对find系列的方法有效
显示等待:
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Firefox()
driver.implicitly_wait(10) # 隐性等待和显性等待可以同时用,但要注意:等待的最长时间取两者之中的大者
driver.get(‘https://huilansame.github.io’)
locator = (By.LINK_TEXT, ‘CSDN’)
简单做法:
如果某一个操作需要长时间加载,可以先改变全局等待时间
例如:
driver.implicitly_wait(60)
这种方式就是如果找不到元素,后面的将不再执行。解决办法是:
try:
wo = driver.find_element_by_id('forecastID')
if ele.text.xxxxxxxxxxxx:
print 通过
else:
print 不通过
except:
print(exception happened)
finally:
driver.implicitly_wait(10)
ID名称不规则的可能会变动,判断方法为刷新页面后是否不变,如果不变则可以用
frame处理: 内联框架
切换到frame里面:
driver.switch_to.frame(‘kw’) #括号里是国中之国的name or id or 索引值
frame 元素的name属性或id属性
索引值(从0开始):0
frame 所对应的webelement :driver.find_element_by_tag_name(‘iframe’)
切换回主HTML里面:
driver.switch_to.default.content()
注意那些会变的ID:
如果有多个frame ,可以直接用frame的名字或ID
css选择器
根据tag名
p{color:red;}
根据id
#food{color:red;}
根据class
.vegetable {color:red;}
根据tag名和class组合写(如果多个)
span.vegetable {color:red;}
span .vegetable 和span.vegetable 是不同的意思,前者表示在span 标签中选择vegetable ,否则是在span后代中选择.vegetable
后代选择器:
选择元素内部的元素
语法:
选择s1元素里面所有的s2元素
可以是直接子节点,也可以不是
比如:
#choose_car option
footer p
可以是很多级
ul ol li em {color:blue;}
第7节课:css高级用法
子元素选择器
#food >ul>ol>li>em
#food >span,#food >p #逗号前面和后面是完全独立的2部分
组(group)选择:
组选择同时选择多个元素,逗号隔开
语法,
比如:
p,buttpn
#food, .cheese
组合使用
选择id为food的所有span子元素和所有的p(包括非food的子元素)
#food >sapn,p
选择id为food 的所有span子元素和所有的p子元素
#food >span,#food >p
选择id为food 的所有子元素
#food>*
兄弟节点的选择
选择紧接在另一个元素后的元素,二者有相同的父元素
比如:
#food+div # 表示选择food后面的div元素
#many >div>p.special +p #+表示紧跟着的
选择在另一个元素后的元素,二者有相同的父元素
比如:#food~div #~表示food后面的元素,不是紧挨着的
第8节课:选择框的操作
可以根据元素的属性记属性值来选择元素
比如:
*[style]
*表示所有的具有style 属性的元素会被选中
p[spec=len2]
p[spec = ‘len2’]
表示标签为p 的属性值为spec是len2的元素会被选中
p[spec=‘len2 len3’]
表示标签为p 的属性值为spec是len2 len3的元素会被选中
p[span*=‘len2’]
表示标签为p 的属性值为spec中包含len2 的元素会被选中
p[span^=‘len2’]
表示标签为p 的属性值为spec中以len2开头 的元素会被选中
p[span$=‘len2’]
表示标签为p 的属性值为spec中以len2结尾 的元素会被选中
P[class=‘specia’][name=‘p1’]
表示标签为p 的属性值为class 是specia 和name 是p1的元素会被选中
#choose_car >option:nth-child(1)
表示id是choose_car的option第1个子元素···~~~~~ 选择属于其父元素的第1个子元素的每个 元素。
#choose_car >option:nth-last-child(1)
同上,就是倒数的意思,选择倒数第一个
#choose_car >option:nth-of-type(4)
表示类型为option的类型中的第4个 #选择属于其父元素第二个
元素的每个
元素。
#choose_car >option:nth-last-of-type(4)
同上,倒数第一个
#food >:not§
选择非p的元素,在food里面
更多css的用法请访问:
http://www.w3school.com.cn/cssref/css_selectors.asp
编辑框的一些操作
用clear 方法清除该元素里面字符串
input1.clear()
获取input1元素里面输入的文本内容
input1.get_attribute(‘value’)
单选框:
type类型是radio
click方法选择
不管原来该元素是否选中,直接点击该元素没有问题
都可以确保该单选框选中
勾选框
type类型是 CheckBox
首先获取选择的状态
sleck = self.wd.find_element_by_css_selector(" div:nth-of-type(3) td .ng-binding span ")
sleckd=sleck.is_selected()
if sleckd:
print('已经选中')
else:
print('选中了')
sleck.click()
复选框:
type类型是select
from selenium.webdriver.support.ui import Select
导入select包
获得相应的WebElement
select = Select(driver.find_element_by_id(“multi”))
导入 Select
from selenium.webdriver.support.ui import Select
获得相应的WebElement
select = Select(driver.find_element_by_id(“multi”))
先去选择所有的 选项
select.deselect_all()
select.select_by_visible_text(“雅阁”)
select.select_by_visible_text(“宝马 740”)
或者select.select_by_value(‘title’)
如果是单一的选择框可以直接选择:
获得相应的WebElement
select = Select(driver.find_element_by_id(“single”))
select.select_by_visible_text(“男”)
第9节课:xpath 选择
xpath 是W3C定义的用来在xml文档中选择节点的语言
主流浏览器也支持XPATH语法
移动端的应用只能用xpath,不支持css
根节点:
根节点用/表示
对应整个HTML
/html/body/div 一级一级
// 表示从当前路径选择 所有后代元素 也就是相对路径的意思
//name[@id=‘xiaoxiao’]
$$(’’)
$x #console xpath写法
//div/p #表示p是div的直接子节点
//div//p #表示p不是div的直接子节点
通配符
和css一样,xpath
//div/*
根据属性进行选择
//name[@id=‘xiaoxiao’]
注意:css中如果是属性值,如果没有空格可以不加引号
但是,xpath必须要引号,单引号和双引号都可以
根据id、class选择
//div[@id=‘food’]
//div[@class=‘chess’]
子元素的选择
选择属于其父元素的第N个某个类型的子元素
//p[2] 等价于 p:nth-of-type(2)
//[@id=‘food’]/p[1] 等价于 #food >p:nth-of-type(1)
//[@id=‘food’]/*[1] =#food >p:nth-chind(3)
选择属于其父元素的倒数第N个某个类型的子元素
//span[last()-1] 属于其父元素的倒数第二个span
//[@id=‘food’]/span[last()]
//[last()-1]
//[last()] #表示最后一个元素
//[last()-1] #表示倒数第2个元素
//p[last()-2] #表示倒数第3个元素 等价于p:nth-last-of-type(3 )
子元素选择
选择属于其父元素的第N个子元素
//[2]等价于//[position()=2] 等价于*:nth-chind(2)
//[@id=‘food’]/[position()=3] #id是food元素的子元素的等于3 position()是位置函数
//[@id=‘food’]/[position()❤️] #id是food元素的子元素的前2个
//[@id=‘food’]/[position()<=3] #id是food元素的子元素的前3个
选择属于其父元素的倒数第N个的子元素
//[id=‘food’]/[last()-1]等价于
//[@id=‘food’]/[position()=last()-1] #position()相当于下标
#id是food元素的子元素的倒数4个
倒数一定用last()
组选择
用多个表达式一起
css用,分开
比如p,button
xpath用|分开
//p|//button
等价于p,button
#food ~div
等价
//*[@id=‘food’]/following-sibiling::div #后面的所有的兄弟节点为div的
//*[@id=‘food’]/preceding-sibiling::div #前面的所有的div节点
#food+div
等价
//[@id=‘food’]/following-sibiling::[1]
选择父节点:
//[@id=‘food’]/… #上一层节点
//[@id=‘food’]/…/… #上上层节点
//span[@price>50] #比较大小
xpath(’.//p’) #表示在当前目录下面找p
更多xpath用法:
http://www.w3school.com.cn/xpath/xpath_syntax.asp
第11节课:selenium 实用技巧
webDriver对象的一些方法
driver.implicitly_wait(10) 只对find等方法有效
获取当前窗口的title
driver.title
获取当前窗口的地址
driver.current_url
随着用户的操作,title和current url会变化
截屏
driver.get_screenshot_as_file(‘ssl.png’)
针对元素的截图目前还没有支持
针对新功能可以搜索、或者猜想
切换窗口:
切换到新的窗口里面操作
循环遍历 driver.window_handles
driver.switch to_window(handle)方法切入新窗口
检查该窗口特点,是否为要切入的那个
切换到最初的窗口:
保存主窗口的hanldc
关闭窗口
close方法
新打开标签页和新打开窗口对自动化测试没有区别
在切换之前保存原来窗口:
#保存主窗口handle
mainWindow = driver.current_window_handle
#检查所有打开窗口中有title是百度的 :
for handle in driver.window_handles:
# 切换到新窗口
driver.switch_to.window(handle)
# 检查是否是我们要进入的window
if ‘百度’ in driver.title:
break
driver.quit() #关闭所有窗口
driver.close() #关闭当前窗口
弹出对话框:它不是HTML的一部分,而是浏览器内置的内容
alert (单一按钮)
操作方法:
driver.switch_to.alert.accept() #点击ok
获取弹窗上面的文本信息:
driver.find_element_by_id(‘h’).click()
print(driver.switch_to.alert.text)
confirm #有ok和取消按钮
driver.switch_to.alert.accept() #点击ok
driver.switch_to.alert.dismiss() #点击取消
prompt #输入文本信息
driver.switch_to.alert.send.keys(‘你好’)
driver.switch_to.alert.accept() #点击ok
其它按钮
实用技巧:
容易消失的元素的查看技巧;
鼠标移到该元素上面才会出现
鼠标移开就会消失
在浏览器console中执行:
setTimeout(function(){debugger;},5000) #先执行这个命令,然后在界面中找元素
上传文件的技巧:
先导入库:
import win32com.client
固定写法
shell=win32com.client.Dispatch(“WScript.Shell”)
上传的文件路径
shell.SendKeys(r’D:\TTT\untitled\samples_selenium\wd\lesson06\cc.png’+’\r\n’)
另一种上传方法:
driver.find_element_by_class_name(‘upload-pic’).send_keys(r’C:\Users\jack\Desktop\cc.png’)
上传过程中不要动鼠标
文件下载路径配置:基于Chrome
options = webdriver.ChromeOptions()
options.add_experimental_option(“prefs”, {
“download.default_directory”: r"C:\Users\jack\Desktop\file",
“download.prompt_for_download”: False,
“download.directory_upgrade”: True,
“safebrowsing.enabled”: True
})
driver = webdriver.Chrome(chrome_options=options,executable_path=r’d:\tools\webdriver\chromedriver.exe’)
第13节课:selenium实用技巧2
浏览器copy
异常捕获,并退出浏览器:
try:
driver.get(‘file:///D:/gsync/workspace/sq/selenium/samples_selenium/wd/lesson07/ac.html’)
t1 = driver.find_element_by_id('1t')
t2 = driver.find_element_by_id('t2')
t3 = driver.find_element_by_id('t3')
except:
print(traceback.format_exc())
finally:
driver.quit()
鼠标悬停
ActionChains 类
anInstance.actionl().action2().actionN().perform()
移动到某一个元素上面
ActionChains(driver).move_to_element(ele).perform()
from selenium.webdriver.common.action_chains import ActionChains
ac = ActionChains(driver)
ac.move_to_element(driver.find_element_by_id(‘zxnav_1’)).perform()
或者
c =driver.find_element_by_id(‘zxnav_1’)
ActionChains(driver).move_to_element©.perform() #perform()才会执行
页面元素不可见
通常不可见元素都是可以操作的
如果确实需要改变窗口大小
size = driver.get_window_size() #得到当前窗口的大小
driver.set_window_size(1100,size[‘height’])
滚动页面
driver.execute_script(‘window.scrollby(250,0)’)
js脚本,改变窗口大小
driver.execute_script(‘window.scrollBy(1000,0)’)
前端代码动态改变页面
现在很多是前端代码动态改变界面的内容
尤其是很多采用了框架像angular\react\vue 这些都会这样做
开始的时候获取的HTML只是一个模板一样的文档,
xhr :异步请求
StaleElementReferenceException:二次渲染异常提示
解决方法:time.sleep(1)
合理使用半自动化
import winsound
winsound.Beep(1500,3000)