文章目录
selenium 简介
Selenium是最广泛使用的开源Web UI(用户界面)自动化测试套件之一。它最初由Jason Huggins于2004年开发,作为Thought Works的内部工具。 Selenium支持跨不同浏览器,平台和编程语言的自动化。
Selenium可以轻松部署在Windows,Linux,Solaris和Macintosh等平台上。 此外,它支持iOS(iOS,Windows Mobile和Android)等移动应用程序的OS(操作系统)。
Selenium通过使用特定于每种语言的驱动程序支持各种编程语言。Selenium支持的语言包括C#,Java,Perl,PHP,Python和Ruby。目前,Selenium Web驱动程序最受Java和C#欢迎。 Selenium测试脚本可以使用任何支持的编程语言进行编码,并且可以直接在大多数现代Web浏览器中运行。 Selenium支持的浏览器包括Internet Explorer,Mozilla Firefox,Google Chrome和Safari。
Selenium的发展经历了三个阶段,第一个阶段,也就是selenium1的时代,在运行selenium1.0程序之前,我们得先启动selenium server端(selenium remote control),我们简称RC。RC主要包括三个部分:launcher,http proxy,selenium core。其中selenium core是被selenium server嵌入到浏览器页面中的,selenium core内部是一堆javascript函数构成,通过调用这些函数来实现对浏览器的各种操作。
很显然比较繁琐,这并不是最佳自动化解决方案,于是后来有了webdriver。
selenium2 的时代合并了webdriver,也就是我们通常说的selenium,selenium2是默认支持Firefox浏览器的,这点非常方便。当然也支持其他更多浏览器,Ie和chrome浏览器需要下载驱动包,并添加到环境变量下。
selenium3 是2016年十月份左右出来的,并且现在默认安装都是selenium3了,selenium3在selenium2的基础上做了一些调整,最明显的区别就是 selenium2对Firefox的支持最高只支持46及以下版本。selenium3可以支持47以上版本,但是需要下载geckodriver.exe驱动,并添加到环境变量path下。
Selenium目前主要包括以下几个套件:
Selenium IDE IDE是一个Firefox插件,可以录制用户的基本操作,生成测试用例。随后可以运行这些测试用例在浏览器里回放,可将测试用例转换为其他语言的自动化脚本。
Selenium RC RC为核心部分。它使用的编程语言,如Java,C#,PHP,Python、Ruby和Perl强大功能来创建更复杂的测试。Selenium RC 分 为 C l i e n t Libraries(编写测试脚本) 和 Selenium Server(控制浏览器行为)。
Selenium WebDriver WebDriver前身是Selenium RC,可以看作是Selenium RC的替代品,直接发送命令给浏览器,并检索结果。2
Selenium Grid 网格用于运行在不同的机器,不同的浏览器并行测试的工具,目的在于加快测试用例运行的速度,从而减少测试运行的总时间。利用Grid可以很方便地实现在多台机器上和异构环境中运行测试用例。
代码环境
python: 3.6 版本
selenium:2.0 版本
Chrome: 87.0.4280.88 版本
chromedriver: 87.0.4280.88 版本
chromedriver
介绍
操作google浏览器需要先安装驱动,Chrome浏览器版本和 chromedriver 驱动版本需要对应。
下载:
驱动链接
或 驱动链接
Chrome离线版本
安装说明
- 解压下载的文件;
- 将 chromedriver.exe 驱动放到python根目录下(python.exe同路径);
验证是否成功:
执行代码后无报错,则驱动安装成功:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
driver.quit()
定位方法
id定位
定位属性中带有 id 属性的元素
<inputid='kw'>
driver.find_element_by_id('kw')
name定位
定位属性中带有 name 属性的元素
<input name='kw1'>
driver.find_element_by_name('kw1')
tag name 定位
定位页面上的标签,一般情况标签都会重复(不推荐)
注意: 一般页面上标签一样的很多,通过标签无法直接定位到某个元素。
通常用于定位一组元素
<input name='kw1'>
driver.find_element_by_tag_name('input')
link定位 | partial link定位
定位标签中带有文本内容的
partial link 可以模糊匹配
<a href="http://news.baidu.com" target="_blank"class="mnav">新闻</a>
driver.find_element_by_link_text('新闻')
driver.find_element_by_partial_link_text('新')
class定位
定位标签中带有class属性的
class属性有空格是多重属性,取其中一个就行
<a class='na' name='kw1'>新闻 </a>
driver.find_element_by_class_name('na')
xpath 定位
XPath 是一种在XML 文档中定位元素的语言。
// 表示当前页面某个目录下,input 表示定位元素的标签名,[@id=‘kw’] 表示这个元素的id 属性值等于kw;如果不想指定标签名也可以用星号(*)代替, . 表示当前节点。
driver = webdriver.Firefox()
url ="http://www.baidu.com/"
driver.get(url)
driver.find_element_by_xpath("//input[@id='kw']")
css定位
CSS(Cascading Style Sheets)是一种语言,它被用来描述HTML 和XML 文档的表现
driver = webdriver.Firefox()
url ="http://www.baidu.com/"
driver.get(url)
driver.find_element_by_css_selector("#kw")
复数定位
定位到的是一组元素,返回的是list队列,下标是从1开始计数。
id复数定位 find_elements_by_id(self, id_)
name复数定位 find_elements_by_name(self, name)
class复数定位 find_elements_by_class_name(self, name)
tag复数定位 find_elements_by_tag_name(self, name)
link复数定位 find_elements_by_link_text(self, text)
partial_link复数定位 find_elements_by_partial_link_text(self, link_text)
xpath复数定位 find_elements_by_xpath(self, xpath)
css复数定位 find_elements_by_css_selector(self, css_selector
快失传了的定位
它需要两个参数,第一个参数是定位方式,这个由By 提供;第二个参数是定位的值。
from selenium.webdriver.common.by import By
find_element(By.ID, ‘‘kw’’)
find_elements(By.NAME, ‘wd’)
xpath
什么是xpath呢?
官方介绍:XPath即为XML路径语言,它是一种用来确定XML1(标准通用标记语言3的子集)文档中某部分位置的语言。反正小编看这个介绍是云里雾里的,通俗一点讲就是通过元素的路径来查找到这个元素的,相当于通过定位一个对象的坐标,来找到这个对象。
表达式描述/从根节点选取。//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。.选取当前节点。…选取当前节点的父节点。@选取属性。
- xptah也可以通过元素的id、name、class这些属性定位
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
driver.find_element_by_xpath("//*[@id='kw']")# id属性
driver.find_element_by_xpath("//*[@name='wd']")# name属性
driver.find_element_by_xpath("//*[@class='s_ipt']")# class属性
- 其它属性定位方法
driver.find_element_by_xpath("//*[@autocomplete='off']")# 其他属性
- 标签
1.有时候同一个属性,同名的比较多,这时候可以通过标签筛选下,定位更准一点
2.如果不想制定标签名称,可以用*号表示任意标签
3.如果想制定具体某个标签,就可以直接写标签名称
driver.find_element_by_xpath("//input[@autocomplete='off']")# 其他属性
driver.find_element_by_xpath("//input[@id='kw']")# id属性
- 层级
1.如果一个元素,它的属性不是很明显,无法直接定位到,这时候我们可以先找它老爸(父元素)
2.找到它老爸后,再找下个层级就能定位到了
3.要定位的是input这个标签,它的老爸的id=s_kw_wrap.
4.要是它老爸的属性也不是很明显,就找它爷爷id=form
5.于是就可以通过层级关系定位到
driver.find_element_by_xpath("//span[@id='s_kw_wrap']/input")# 父级
driver.find_element_by_xpath("//form[@id='form']/span/input")# 祖父级
- 索引
1.如果一个元素它的兄弟元素跟它的标签一样,这时候无法通过层级定位到。因为都是一个父亲生的,多胞胎兄弟。
2.虽然双胞胎兄弟很难识别,但是出生是有先后的,于是可以通过它在家里的排行老几定位到。
3.用xpath定位老大、老二和老三(这里索引是从1开始算起的,跟Python的索引不一样)
driver.find_element_by_xpath("//select[@id='nr']/option[1]")# 第一个
driver.find_element_by_xpath("//select[@id='nr']/option[2]")# 第二个
driver.find_element_by_xpath("//select[@id='nr']/option[3]")# 第三个
- 逻辑运算
1.xpath还有一个比较强的功能,是可以多个属性逻辑运算的,可以支持与(and)、或(or)、非(not)
2.一般用的比较多的是and运算,同时满足两个属性
driver.find_element_by_xpath("//*[@id='kw' and @autocomplete='off']")
- 模糊匹配
1.xpath还有一个非常强大的功能,模糊匹配
2.掌握了模糊匹配功能,基本上没有定位不到的
3.比如我要定位百度页面的超链接“hao123”,在上一篇中讲过可以通过by_link,也可以通过by_partial_link,模糊匹配定位到。当然xpath也可以有同样的功能,并且更为强大。
driver.find_element_by_xpath("//*[contains(text(), 'hao123')]")# 模糊匹配
driver.find_element_by_xpath("//*[contains(@id, 'kw')]")# 模糊匹配某属性
driver.find_element_by_xpath("//*[starts-with(@id, 's_kw_')]")# 模糊匹配以什么开头
driver.find_element_by_xpath("//*[ends-with(@id, 'kw_wrap')]")# 模糊匹配以什么结尾
driver.find_element_by_xpath("//*[matchs(text(), 'hao123')]")# 正则表达式匹配
css
CSS 是一种描述 HTML 文档样式的语言。
CSS 描述应该如何显示 HTML 元素。
什么是 CSS?
- CSS 指的是层叠样式表* (Cascading Style Sheets)
- CSS 描述了如何在屏幕、纸张或其他媒体上显示 HTML 元素
- CSS 节省了大量工作。它可以同时控制多张网页的布局
- 外部样式表存储在 CSS 文件中
表达式描述#表示 id 属性,eg: #kw.表示class属性, eg: .s_iptpagname直接用标签名称,无任何标示符, eg: input
- 按元素的id、class、标签这些属性定位
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
driver.find_element_by_css_selector("#kw")# id属性
driver.find_element_by_css_selector("input")# 标签属性
driver.find_element_by_css_selector(".s_ipt")# class属性
- 其它属性定位方法
driver.find_element_by_css_selector("[name='wd']")# name属性
driver.find_element_by_css_selector("[autocomplete='off']")# autocomplete属性
driver.find_element_by_css_selector("[type='text']")# type属性
- 标签 + 属性组合
driver.find_element_by_css_selector("input.s_ipt")# 标签 + class属性
driver.find_element_by_css_selector("input#kw")# 标签 + id属性
driver.find_element_by_css_selector("input[id='kw']")# 标签 + 其他
driver.find_element_by_css_selector("input:contains('kw')")# 标签 + 模糊匹配(已删除)
- 层级
driver.find_element_by_css_selector("form#form>span>input")
driver.find_element_by_css_selector("form.fm>span>input")
- 索引
driver.find_element_by_css_selector("select#nr>option:nth-child(1)")# 第一个
driver.find_element_by_css_selector("select#nr>option:nth-child(2)")# 第二个
driver.find_element_by_css_selector("select#nr>option:nth-child(3)")# 第三个
- 逻辑运算
driver.find_element_by_css_selector("input[id='kw'][name='wd']")# 同时匹配两个属性
- 模糊匹配
# <div class="head_wrapper"># <div class="s_form">...</div># <div id="u">...</div># <div id="u1"># <a href="http://news.baidu.com" name="tj_trnews" class="mnav">新闻</a># <a href="http://www.hao123.com" name="tj_trhao123" class="mnav">hao123</a># <a href="http://map.baidu.com" name="tj_trmap" class="mnav">地图</a># <a href="http://v.baidu.com" name="tj_trvideo" class="mnav">视频</a># <a href="http://tieba.baidu.com" name="tj_trtieba" class="mnav">贴吧</a># <a href="http://xueshu.baidu.com" name="tj_trxueshu" class="mnav">学术</a>#前端匹配
driver.find_element_by_css_selector("a[href^='http://map.baidu']")#后端匹配
driver.find_element_by_css_selector("a[href$='//map.baidu.com']")#中间匹配
driver.find_element_by_css_selector("a[href*='//map.baidu.']")
无界面模式
有的时候不想爬数据时候不想显示浏览器,可以设置为无界面模式。
Chrome浏览器设置方式:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('--headless')# 设置chrome浏览器无界面模式
driver = webdriver.Chrome(chrome_options=options)
url ="https://www.baidu.com"
driver.get(req_url)print(driver.page_source)# 输出页面源码
browser.quit()
Firefox浏览器设置方式:
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
options = Options()
options.add_argument('--headless')# 设置firefox浏览器无界面模式
driver = webdriver.Firefox(firefox_options=options)
url ="https://www.baidu.com"
driver.get(req_url)print(driver.page_source)# 输出页面源码
browser.quit()
页面等待方式
- 强制等待 sleep()
设置固定休眠时间,单位为秒。 由python的
time
包提供, 导入 time 包后就可以使用。
缺点:不智能,使用太多的sleep会影响脚本运行速度。
import time
sleep(5)#等待5秒
- 隐式等待 implicitly_wait()
由webdriver提供的方法,一旦设置,这个隐式等待会在WebDriver对象实例的整个生命周期起作用,它不针对某一个元素,是全局元素等待,即在定位元素时,需要等待页面全部元素加载完成,才会执行下一个语句。如果超出了设置时间的则抛出异常。
一般用在打开浏览器后,加入隐式等待,确保浏览器打开正常,在请求url地址。
缺点:当页面某些js无法加载,但是想找的元素已经出来了,它还是会继续等待,直到页面加载完成(浏览器标签左上角圈圈不再转),才会执行下一句。某些情况下会影响脚本执行速度。
driver.implicitly_wait(10)#隐式等待10秒
- 显示等待 WebDriverWait
需要通过
from selenium.webdriver.support.wait import WebDriverWait
导入模块
WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
driver:浏览器驱动
timeout:最长超时时间,默认以秒为单位
poll_frequency:检测的间隔步长,默认为0.5s
ignored_exceptions:超时后的抛出的异常信息,默认抛出NoSuchElementExeception异常。
- 可与
until()
或者until_not()
方法结合使用
在设置时间(10s)内,等待后面的条件发生。如果超过设置时间未发生,则抛出异常。在等待期间,每隔一定时间(默认0.5秒),调用until或until_not里的方法,直到它返回True或False。
WebDriverWait(driver,10).until(method,message="")
调用该方法提供的驱动程序作为参数,直到返回值为True
WebDriverWait(driver,10).until_not(method,message="")
调用该方法提供的驱动程序作为参数,直到返回值为False
- WebDriverWait与expected_conditions结合使用
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
wait = WebDriverWait(driver,10,0.5)
element =waite.until(EC.presence_of_element_located((By.ID,"kw")),message="")# 此处注意,如果省略message=“”,则By.ID外面是三层()
expected_conditions
类提供的预期条件判断的方法
方法说明title_is判断当前页面的 title 是否完全等于(==)预期字符串,返回布尔值title_contains判断当前页面的 title 是否包含预期字符串,返回布尔值presence_of_element_located判断某个元素是否被加到了 dom 树里,并不代表该元素一定可见visibility_of_element_located判断元素是否可见(可见代表元素非隐藏,并且元素宽和高都不等于 0)visibility_of同上一方法,只是上一方法参数为locator,这个方法参数是 定位后的元素presence_of_all_elements_located判断是否至少有 1 个元素存在于 dom 树中。举例:如果页面上有 n 个元素的 class 都是’wp’,那么只要有 1 个元素存在,这个方法就返回 Truetext_to_be_present_in_element判断某个元素中的 text 是否 包含 了预期的字符串text_to_be_present_in_element_value判断某个元素中的 value 属性是否包含 了预期的字符串frame_to_be_available_and_switch_to_it判断该 frame 是否可以 switch进去,如果可以的话,返回 True 并且 switch 进去,否则返回 Falseinvisibility_of_element_located判断某个元素中是否不存在于dom树或不可见element_to_be_clickable判断某个元素中是否可见并且可点击staleness_of等某个元素从 dom 树中移除,注意,这个方法也是返回 True或 Falseelement_to_be_selected判断某个元素是否被选中了,一般用在下拉列表element_selection_state_to_be判断某个元素的选中状态是否符合预期element_located_selection_state_to_be跟上面的方法作用一样,只是上面的方法传入定位到的 element,而这个方法传入 locatoralert_is_present判断页面上是否存在 alert
示例:
- 元素出现:until()1.until里面有个lambda函数,这个语法看python文档吧2.以百度输入框为例
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
driver = webdriver.Firefox()
driver.get('http://www.baidu.com')# 等待时长10S,默认0.5S询问一次
WebDriverWait(driver,10).until(lambda x:x.find_element_by_id('kw')).send_keys('python')
- 元素消失:until_not()1.判断元素是否消失,是返回Ture,否返回False备注:此方法未调好,暂时放这
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
driver = webdriver.Firefox()
driver.get('http://www.baidu.com')# 等待时长10S,默认0.5S询问一次
WebDriverWait(driver,10).until(lambda x:x.find_element_by_id('kw').send_keys('python'))# 判断id为[kw00]元素是否消失
is_disappeared = WebDriverWait(driver,10,1).until_not(lambda x:x.find_element_by_id('kw00').is_displayed())print(is_disappeared)#> True
操作事件
- 输入框输入 send_keys
注意: send_keys输入中文时,需要在字符串前面加 u (unicode编码)
send_keys('内容')
- 鼠标点击 click
click()
- 清空输入框 clear
clear()
- 回车 submit
submit()
JS处理滚动条
通过webdriver提供的execute_script()方法执行JS脚本操作滚动条
- 右侧滚动条Firefox浏览器和Chrome浏览器用的语法不一样,下面区分列出来,貌似谷歌浏览器71版通用火狐了js = “var q=document.documentElement.scrollTop=10000” # Firefox浏览器滚动到底部js = “var q=document.documentElement.scrollTop=0” # Firefox浏览器滚动到顶部js = “var q=document.body.scrollTop=10000” # Chrome浏览器滚动到底部js = “var q=document.body.scrollTop=0” # Chrome浏览器滚动到顶部js = “var q=document.getElementById(‘id’).scrollTop=0” # 通过id属性切入操作内嵌表单的滚动条
- 横向滚动条js = “window.scrollTo(x,y);” # x为横向距离 y为纵向距离
- 据说不存在兼容问题的scrollTo函数–scrollHeight 获取对象的滚动高度。 –scrollLeft 设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离。 –scrollTop 设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离。 –scrollWidth 获取对象的滚动宽度js = “window.scrollTo(0,document.body.scrollHeight)” # 滚动到底部js = “window.scrollTo(0,0)” # 滚动到顶部js = “window.scrollTo(x,y)” # 滚动到横向距离为X纵向距离为Y的位置
- 执行js脚本driver.execute_script(js)
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.set_window_size(width=800,height=700)
driver.get("https://www.baidu.com")
driver.find_element_by_xpath("//input[@id='kw']").send_keys('selenium')
driver.find_element_by_xpath("//input[@id='su']").click()
js ="window.scrollTo(0,document.body.scrollHeight)"
driver.execute_script(js)
js ="window.scrollTo(500,0)"
driver.execute_script(js)
driver.quit()
- 元素聚焦元素聚焦–通过JS让页面直接跳到元素出现的位置(注意遮盖现象,聚焦被遮盖聚焦附近元素)
target = driver.find_element_by_xpath()
driver.execute_script(“arguments[0].scrollIntoView();”, target)
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.find_element_by_xpath("//input[@id='kw']").send_keys('selenium')
driver.find_element_by_xpath("//input[@id='su']").click()
driver.set_window_size(width=600, height=600)
target = driver.find_element_by_xpath("//*[@id='page']/a[1]/span[2]")
driver.execute_script("arguments[0].scrollIntoView();", target)# 元素聚焦到翻页按钮 - 2
driver.quit()
切换iframe
driver.switch_to_frame(name or id or frame_element)
默认可以用: id 或 name 直接定位
- 切换,通过页面上 iframe 的位置定位
用frame的index来定位,第一个是0
driver.switch_to.frame(0)
- 切换,通过页面上id 或 name 属性定位
注意: 如果id的值是动态的也不能定位到
<iframe name="aa"id="x-URS-iframe1610006384373.8518"></iframe>
driver.switch_to.frame('x-URS-iframe1610006384373.8518')# id定位
driver.switch_to.frame('aa')# name定位
- 切换,通过 find_element 定位
<iframe name="aa"id="x-URS-iframe1610006384373.8518"></iframe>
frame = driver.find_element_by_xpath('//iframe[@id="x-URS-iframe"]')# 先定位元素
driver.switch_to.frame(frame)# 在切换iframe
- 切换多个 iframe
# 从Top Windows切换到框架f1
driver.switch_to_frame('f1')# 从框架f1到框架f2
driver.switch_to_frame('f2')
- 返回上一级
driver.switch_to.parent_frame()# 返回上一级
- 跳出 iframe 返回到 Top windows 上
driver.switch_to_default_content()
切换窗口
- 获取当前句柄
driver.current_window_handle # 返回 str
- 获取所有句柄
handles = driver.window_handles # 返回 list
- 切换指定句柄
handle = handles[-1]# 取最新的窗口id
driver.swith_to.window(handle)# 切换窗口
select 下拉框
说明: 标签名为 select 的都是下拉框属性
#示例: 打开百度-设置-搜索设置:<select id="nr" name="NR"><option selected="" value="10">每页显示10条</option><option value="20">每页显示20条</option><option value="50">每页显示50条</option>
- 二次定位思路:1.先定位select框; 2.再定位下拉框内容;
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.select import Select
driver = webdriver.Firefox()
driver.get("https://www.baidu.com")
driver.implicitly_wait(20)# 鼠标移动到“设置”按钮
mouse = driver.find_element_by_link_text("设置")
ActionChains(driver).move_to_element(mouse).perform()# 鼠标移动
driver.find_element_by_link_text("搜索设置").click()# 定位下拉框内容并点击
driver.find_element_by_id("nr").find_element_by_xpath("//option[@value='50']").click()
- 直接定位思路:1. 用定位方法,一次性直接定位到option上的内容
driver.find_element_by_xpath("//*[@id='nr']/option[2]").click()
- select 模块专门定位方法导入模块:
from selenium.webdriver.support.select import Select
a) 通过select选项的索引来定位选择对应选项(从0开始计数),如选择第三个选项:select_by_index(2)
# 鼠标移动到“设置”按钮
mouse = driver.find_element_by_link_text("设置")
ActionChains(driver).move_to_element(mouse).perform()# 鼠标移动
driver.find_element_by_link_text("搜索设置").click()# select模块定位
s = driver.find_element_by_id("nr")
Select(s).select_by_index(2)# 通过索引方式定位
b) 还可以通过select内容的值进行定位:
s = driver.find_element_by_id("nr")
Select(s).select_by_value("20")# 通过值方式定位
c) 还可以直接通过选项的文本内容来定位:
s = driver.find_element_by_id("nr")
Select(s).select_by_visible_text("每页显示50条")
d) 其他方法:
select_by_index() :通过索引定位
select_by_value() :通过value值定位
select_by_visible_text() :通过文本值定位
deselect_all() :取消所有选项
deselect_by_index() :取消对应index选项
deselect_by_value() :取消对应value选项
deselect_by_visible_text() :取消对应文本选项
first_selected_option() :返回第一个选项
all_selected_options() :返回所有的选项
弹窗处理 alert\confirm\prompt
alert\confirm\prompt弹出框操作主要方法有:
text: # 获取文本值
accept() : # 点击"确认"
dismiss() : # 点击"取消"或者叉掉对话框
send_keys() :# 输入文本值 --仅限于prompt,在alert和confirm上没有输入框
alert 弹窗特点: 文本内容 + 确认按钮
confirm 弹窗特点: 文本内容 + 确认按钮 + 取消按钮
prompt 弹窗特点: 文本内容 + 输入框 + 确认按钮 + 取消按钮
以上弹窗页面示例:
<html><head><title>Alert</title></head><body>
<input id = "alert" value = "alert" type = "button" onclick = "alert('alert弹窗示例!');"/>
<input id = "confirm" value = "confirm" type = "button" onclick = "confirm('confirm弹窗示例!');"/>
<input id = "prompt" value = "prompt" type = "button" onclick = "var name = prompt('这是什么弹窗:','prompt 弹窗示例'); document.write(name) "/>
</body></html>
- alert 弹窗思路: 1.先用switch_to_alert()方法切换到alert弹出框上; 2.可以用text方法获取弹出的文本 信息; 3.accept()点击确认按钮; 4.dismiss()相当于点右上角x,取消弹出框;
driver.find_element_by_id("alert").click()
al = driver.switch_to_alert()print(al.text)# 获取文本内容
al.accept()# 点击确认按钮
al.dismiss()# 点击 x 关闭按钮
- confirm 弹窗思路:同 alert 弹窗
driver.find_element_by_id("confirm").click()
co = driver.switch_to_alert()print(co.text)# 获取文本内容
co.accept()# 点击确认按钮
co.dismiss()# 点击 x 关闭按钮
- prompt 弹窗思路:同 alert 弹窗,输入框可以用 send_keys() 方法输入文本内容
driver.find_element_by_id("prompt").click()
pr = driver.switch_to_alert()print(pr.text)# 获取文本内容
pr.send_keys('要输入的内容')# 输入框输入内容
pr.accept()# 点击确认按钮
pr.dismiss()# 点击 x 关闭按钮
- 自定义弹窗思路:这种弹窗可以利用HTML DOM Style 对象,有一个display属性,可以设置元素如何被显示,将display的值设置成none就可以去除这个弹窗了。
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://sh.xsjedu.org/")
js ='document.getElementById("doyoo_monitor").style.display="none";'
driver.execute_script(js)
鼠标事件
from selenium.webdriver.common.action_chains import ActionChains
- move_to_element() 鼠标悬停 重点掌握
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
driver = webdriver.Firefox()
driver.get("https://www.baidu.com")
mouse = driver.find_element_by_link_text("设置")
ActionChains(driver).move_to_element(mouse).perform()
driver.find_element_by_link_text("搜索设置").click()
- drag_and_drop(source, target) 拖动
source: 鼠标拖动的源元素。
target: 鼠标释放的目标元素。
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()# 定位元素的源位置
element = driver.find_element_by_id("xxx")# 定位元素要移动到的目标位置
target = driver.find_element_by_id("xxx")# 执行元素的拖放操作
ActionChains(driver).drag_and_drop(element, target).perform()
- context_click() 右击
- double_click() 双击
键盘事件
- 模块from selenium.webdriver.common.keys import 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.F5)键盘F5 send_keys(Keys.F12) 键盘F12
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")# 输入框输入内容
driver.find_element_by_id("kw").send_keys("seleniumm")# 删除多输入的一个m
driver.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')
页面截图方法
### webdriver 自带的四种截图方法
- get_screenshot_as_file(self, filename)获取当前window的截图,出现IOError时候返回False,截图成功返回True。当filename参数是文件名时,文件保存路径同脚本路径。
# filename 保存文件的路径driver.get_screenshot_as_file('/Screenshots/foo.png')
- save_screenshot(self)根据源码,save_screenshot方法是调用的 get_screenshot_as_file方法,以下是源码:
defget_screenshot_as_file(self, filename): png = self.get_screenshot_as_png()try:withopen(filename,'wb')as f: f.write(png)except IOError:returnFalsefinally:del png returnTrue save_screenshot = get_screenshot_as_file
- get_screenshot_as_base64(self)获取屏幕截图,保存的是base64的编码格式,在HTML界面输出截图的时候,会用到。 比如,想把截图放到html测试报告里。
driver.get_screenshot_as_base64()
- get_screenshot_as_png(self)获取屏幕截图,保存的是二进制数据,很少用到。
driver.get_screenshot_as_png()
- 获取页面的宽度和高度
width = driver.execute_script("return document.documentElement.scrollWidth")height = driver.execute_script("return document.documentElement.scrollHeight")driver.set_window_size(width, height)# 设置窗口大小
- 获取元素的宽度和高度
ele = self.findElement(location)# 定位元素left = ele.location['x']top = ele.location['y']high = ele.location['x']+ ele.size['width']# 高度wide = ele.location['y']+ ele.size['height']# 宽度
JS 处理日历控件(readonly属性)
思路:先用js去掉readonly属性,然后直接输入日期文本内容
1.日历控件
a.打开12306的车票查询界面,在出发日期输入框无法直接输入时间
b.常规思路是点开日历控件弹出框,从日历控件上点日期,这样操作比较烦躁,并且我们测试的重点不在日历控件上,只是想输入个时间,做下一步的操作
c.用firebug查看输入框的属性:readonly=“readonly”,如下:
<inputid="train_date"class="inp-txt"type="text" value="" name="leftTicketDTO.train_date" autocomplete="off" maxlength="10" readonly="readonly">
2.去掉readonly属性
a.很明显这种元素的属性是readonly,输入框是无法直接输入的,这时候需要先去掉元素的readonly属性,然后就可以输入啦。
b.找到对应元素,直接删除readonly=“readonly”,然后回车。
c.在页面出发日位置就可以输入日期的数据。
3.用 js 删除属性
a.用js去掉元素属性基本思路:先定位到元素,然后用removeAttribute(“readonly”)方法删除属性。
b.出发日元素id为:train_date,对应js代码为:
js ='document.getElementById("train_date").removeAttribute("readonly");'
driver.execute_script(js)
4.输入日期
a.输入日期前,一定要先清空文本,要不然无法输入成功的。
b.这里输入日期后,会自动弹出日历控件,随便点下其它位置就好了!
js ='document.getElementById("train_date").removeAttribute("readonly");'
driver.execute_script(js)
driver.find_element_by_id("train_date").clear()
driver.find_element_by_id("train_date").send_keys("2016-12-25")
5.js方法输入日期
a.这里也可以用js方法输入日期,其实很简单,直接改掉输入框元素的value值就可以啦
js ='document.getElementById("train_date").removeAttribute("readonly");'
driver.execute_script(js)
js_value ='document.getElementById("train_date").value="2021-01-01"'
driver.execute_script(js_value)
js处理内嵌div滚动条
HTML内嵌滚动条示例:
<!DOCTYPE html><meta charset="UTF-8"><!--for HTML5 --><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><html><head><style type="text/css">
div.scroll
{
background-color:#afafaf;
width:500px;
height:100px;
overflow:auto;}</style></head><body><p>这是一个内嵌的div滚动条</p><div id="tang" name="test"class="scroll">这是一个内嵌div:民国年间,九大家族镇守长沙,被称为“九门提督”。这九门势力庞大,外八行的无人不知,无人不晓,几乎所有冥器,流出长沙必然经过其中一家。
1933年秋,一辆神秘鬼车缓缓驶入长沙火车站,九门之首“张大佛爷”张启山身为布防官,奉命调查始末。张启山与八爷齐铁嘴一路探访,发现长沙城外有一座疑点重重的矿山,一直被日本人窥伺。
为破解矿山之谜,张启山求助同为九门上三门的戏曲名伶二月红,无奈二月红虽出身考古世家,却心系重病的妻子丫头,早已金盆洗手。张启山为了国家大义和手足之情,北上去往新月饭店为二月红爱妻求药。在北平,张启山邂逅了新月饭店的大小姐尹新月,并为尹新月连点三盏天灯,散尽家财。尹新月帮助张启山等人顺利返回长沙,二人暗生情愫。二月红爱妻病入膏肓,服药后不见好转,最终故去。
二月红悲伤之余却意外发现家族祖辈与矿山亦有重大关联,于是振作精神,决定与张启山联手,解开矿山之谜</div></body></html>
1.纵向滚动
div的属性:
<div id="tang" name="test" class="scroll">
js_d ='document.getElementById(tang).scrollTop=10000'
driver.execute_script(js_d)# 底部
js_t ='document.getElementById(tang).scrollTop=0'
driver.execute_script(js_t)# 顶部
2.横向滚动条
js_d ='document.getElementById(tang).scrollLeft=10000'
driver.execute_script(js_d)# 右部
js_t ='document.getElementById(tang).scrollLeft=0'
driver.execute_script(js_t)# 左部
3.用class属性定位
a.js用class属性定位,返回的是一个list对象,这里取第一个就可以了。
js_d ='document.getElementByClassName("scroll")[0].scrollTop=10000'
driver.execute_script(js_d)# 纵向底部
js_a ='document.getElementByClassName("scroll")[0].scrollLeft=10000'
driver.execute_script(js_a)# 横向右部
问题
1. selenium 原理是什么?
Selenium是一个用于Web应用程序测试框架,支持多平台、多浏览器、多语言去实现自动化测试;
常用的是 selenium webdirver,它有客户端和服务端,主要通过驱动程序驱动浏览器实现自动化;
它是采用 Http 的通讯协议,将客户端(脚本代码)的指令通过 http 请求发送给驱动程序,驱动程序收到后,就会发送到服务端(浏览器)做相应的操作。
2. webdriver client的原理是什么?
当测试脚本启动firefox的时候,selenium-webdriver 会首先在新线程中启动firefox浏览器。如果测试脚本指定了firefox的profile,那么就以该profile启动,否则的话就新启1个profile,并启动firefox;
firefox一般是以-no-remote的方法启动,启动后selenium-webdriver会将firefox绑定到特定的端口,绑定完成后该firefox实例便作为webdriver的remote server存在;
客户端(也就是测试脚本)创建1个session,在该session中通过http请求向remote server发送restful的请求,remote server解析请求,完成相应操作并返回response;
客户端接受response,并分析其返回值以决定是转到第3步还是结束脚本;
webdriver是按照server – client的经典设计模式设计的。
server端就是remote server,可以是任意的浏览器。当我们的脚本启动浏览器后,该浏览器就是remote server,它的职责就是等待client发送请求并做出相应;
client端简单说来就是我们的测试代码,我们测试代码中的一些行为,比如打开浏览器,转跳到特定的url等操作是以http请求的方式发送给被 测试浏览器,也就是remote server;remote server接受请求,并执行相应操作,并在response中返回执行状态、返回值等信息;
3. 启动浏览器的时候用到的是哪个webdriver协议?
http协议
4. selenium中如何判断元素是否存在?
首先selenium里面是没有这个方法的,判断元素存在需要自己写一个方法了。
元素存在有几种形式,一种是页面有多个元素属性重复的,这种直接操作会报错的;还有一种是页面隐藏的元素操作也会报错
5. 你的自动化用例的执行策略是什么?
集成到jenkins一键执行,可以手动执行,也可以定时执行。
6. 如何在定位元素后高亮元素(以调试为目的)?
1.js方法,直接让该元素置顶
2.要是点击后没高亮,就用js去修改属性吧(万能的js)
版权归原作者 CS_Hoyun 所有, 如有侵权,请联系我们删除。