一、selenium介绍

selenium是一个用于测试web程序的工具。selenium测试直接运行在浏览器上,就像真正的用户在操作浏览器一样。

selenium的主要功能有:测试与浏览器的兼容性,测试应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能,创建回归测试检验软件功能和用户需求。

selenium的优点:

  • 免费且开源
  • 支持linux、windows、macos系统
  • 支持IE、Chorme、Firefox、 Safari、Opera等浏览器
  • 支持Java、Python、Ruby、JS、C#、PHP语言等编程语言
  • 可以轻松地与其他工具进行集成,例如unittest、pytest、Junit、TestNG、Maven、Jenkins等
  • 通过Selenium Grid实现并行分布式测试

二、selenium安装

1.安装selenium

pip install selenium

2.下载驱动

不同的浏览器的不同版本下载不同的驱动,驱动下载解压,然后添加环境变量。下载驱动地址:https://www.selenium.dev/documentation/en/webdriver/driver_requirements/

如果要打开IE浏览器的话,需要在浏览器的Internet选项中的安全页里有4个安全选项,Internet、本地Internet、受信任的站点、受限制的站点,这4个里面都有一个启用保护模式,都需要勾选上才可以,还得把驱动的路径加入到环境变量中。

三、selenium启动浏览器

本文以python语言,Chorme浏览器为例

1.启动浏览器

from selenium import webdriver

driver = webdriver.Chrome()  #启动浏览器
driver.get("https://www.baidu.com") #在浏览器中打开百度页面

driver.quit() #退出浏览器

2.屏蔽chrome浏览器的信息提示栏

selenium rrmoteserver起什么作用 selenium的功能与作用_标签名

from selenium import webdriver

options = webdriver.ChromeOptions() #设置chrome浏览器选项
# options.add_argument('disable-infobars') #这种方式失效了
options.add_experimental_option("excludeSwitches",['enable-automation'])
driver = webdriver.Chrome(chrome_options=options)
driver.get("https://www.baidu.com")
driver.quit()

3.chrome浏览器模拟手机

selenium rrmoteserver起什么作用 selenium的功能与作用_css_02

from selenium import webdriver

mobileEmulation = {"deviceName":"iPhone 6"}  #设置手机型号,都是比较老的机型
options = webdriver.ChromeOptions()
options.add_experimental_option("mobileEmulation",mobileEmulation)
driver = webdriver.Chrome(chrome_options=options)
driver.get("https://www.baidu.com")

driver.quit()

4.设置无头模式

# chrome无头浏览
from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--headless")  #设置无头浏览
options.add_argument("log-level=1") #设置log显示等级为1,默认为0,不然会有很多info信息打印;INFO=0 WARNING=1 LOG_ERROR =2 LOG_FATAL=3
driver = webdriver.Chrome(chrome_options=options)
driver.get("http://www.baidu.com")
element = driver.find_element_by_id("kw")
print(element.get_attribute("outerHTML"))
driver.quit()

5.设置浏览器窗口大小

driver.set_window_size(400,800)  #设置浏览器窗口大小为宽400,高800
driver.maximize_window()  #最大化浏览器窗口
driver.minimize_window()  #最小化浏览器窗口

 6.浏览器的前进后退和刷新

driver.forward()  #前进
driver.back()  #后退
driver.refresh()  #刷新

7.浏览器的关闭

driver.close()  #关闭浏览器当前页面
driver.quit()  #关闭浏览器所有页面和驱动

四、selenium定位方式

在操作页面元素之前我们首先要对页面元素进行定位,元素定位的过程就是查找HTML元素的过程。find_element通过定位方式查找一个元素,如果有多个返回第一个;find_elements通过定位方式查找所有符合条件的元素,返回一个list

selenium rrmoteserver起什么作用 selenium的功能与作用_css_03

1.使用元素的属性定位

element = driver.find_element_by_id("kw")  #通过元素的id属性值定位,id属性通常都是唯一的,但是id可能是动态的
element = driver.find_element_by_name("wd")  #通过元素的name属性值定位,name属性不一定是唯一的
element = driver.find_element_by_class_name("s_ipt") #通过元素的class属性值定位,class属性不一定是唯一的
element = driver.find_elements_by_tag_name("input")  #通过元素的标签名称定位,元素名称通常都不止只有一个,经常用find_elements_by_tag_name定位一组元素
element = driver.find_element_by_link_text("1石家庄今日新增确诊病例26例新")  #通过有超链接的元素文本定位,需要输入完整的文内内容,否则会定位失败;一般用来定位页面上的超链接
element = driver.find_element_by_partial_link_text("石家庄今日新增确诊病例26例")  #通过有超链接的元素的部分文本定位,一般用来定位页面上的超链接

2.使用xpath定位

xpath 是一门在 XML 文档中查找信息的语言,了解相关信息https://www.w3school.com.cn/xpath/index.asp

element = driver.find_element_by_xpath('xpath路径')

2.1 使用绝对路径定位:从根节点开始一层一层查找

/表示绝对路径,例如使用driver.find_element_by_xpath("html/body/div/div/div/div/div/form/span/input")可以定位到百度搜索输入框,但是繁琐

2.2通过相对路径定位

//表示相对路径,.表示当前元素,..表示父元素

  • 通过属性定位,//*代表所有标签名,//*[@属性名="属性值"]
  • 使用标签+属性查找;//标签名[@属性名="属性值"];
  • 使用层级定位,先定位目标标签的父标签来定位子标签;//父标签名[@父标签属性名="父标签属性值"]/子标签;层级定位不限于两层,可以是多层的
  • 索引,当一个父标签有多个相同标签名的子标签时使用;//父标签名[@父标签属性名="父标签属性值"]/子标签[索引值];xpath的索引值是从1开始的;不写标签值,如果有多个相同子标签默认定位第一个
  • 逻辑and/or/not,当元素属性与其他元素有相同的部分,需要使用多个属性定位一个元素时使用and连接多个属性;//标签名[@属性名1="属性值1" and @属性名2="属性值2"]
  • text关键字,//*[text()="百度一下"] 文本是百度一下的元素
  • 模糊匹配,contains包含,starts-with匹配开头,ends-with匹配结尾,matchs正则匹配;//*[contain(@属性名,"部分属性值")]
  • | 连接符 通过在路径表达式中使用|,可以选取若干个路径;//div/p | //input查找div标签下的所有p标签和所有input标签
  • 通过轴定位关联标签;//标签名称/轴名称::标签名称;轴名称:
  • ancestor:祖先节点 包括父
  • parent:父节点
  • prceding-sibling:当前元素节点标签之前的所有兄弟节点
  • prceding:当前元素节点标签之前的所有节点 
  • following-sibling:当前元素节点标签之后的所有兄弟节点
  • following:当前元素节点标签之后的所有节点 
element = driver.find_element_by_xpath('//input[@id="kw"]') #利用标签名+属性定位百度搜索框
element = driver.find_element_by_xpath('//*[@name="wd" and @class="s_ipt"]') #利用2种属性定位百度搜索框
element = driver.find_element_by_xpath('//div[@id="s-top-left"]/a[2]')  #利用层级定位和索引定位百度页面左上角的hao123超链接地址

3.使用CSS定位

css是一种语言,用来描述HTML和XML文档的表现。css使用选择器来为页面元素绑定属性,这些选择器可以被selenium用作定位。css比xpath定位快

element = driver.find_element_by_css_selector('css表达式')

3.1通过属性定位,id用#表示,#kw;class用.表示,.s_ipt;其实属性使用属性名,[属性名="属性值"];还可以加上标签,标签名[属性名="属性值"]

3.2使用层级定位,父标签[父标签属性名="父标签属性值"]>子标签

3.3使用索引定位,父标签[父标签属性名="父标签属性值"]>子标签:nth-child(索引值),索引值从1开始;nth-child(索引值)表示父标签下所有子标签的顺序值,可省略子标签名;父标签[父标签属性名="父标签属性值"]>p:nth-of-type(n) 表示父标签下第n个p标签

3.4使用逻辑定位,标签名[属性名1="属性值1"][属性名2="属性值2"] 表示and

3.5使用模糊匹配,^表示匹配开头,$匹配结尾,*表示包含;标签名[属性名*="属性值"]

element = driver.find_element_by_css_selector('#kw')  #利用id属性定位百度搜索框
element = driver.find_element_by_css_selector('input[name="wd"][class*="ipt"]') #利用2种属性定位百度搜索框
element = driver.find_element_by_css_selector('div#s-top-left>a:nth-child(2)') #利用层级定位和索引定位百度页面左上角的hao123超链接地址

4.如何选择元素定位

如果有标签有id属性,使用id定位;如果没有id,或者id是动态的,使用xpath或css定位,css定位更快,推荐使用css;如果有超链接,使用link_text或partial_link_text定位

5.复制xpath路径和css路径

selenium rrmoteserver起什么作用 selenium的功能与作用_css_04

五、元素操作

element.click()  #点击
element.send_keys("输入的内容")  #输入
element.clear()   #清空
element.submit()  #用于表单提交
element.size  #获取元素的尺寸大小
element.text  #获取元素的文本
element.tag_name  #获取元素标签名
driver.title  #获取当前页面的标题
driver.current_url   #获取当前页面的url
element.get_attribution("属性名")  #获取元素的属性值
element.is_displayed()  #判断元素是否可见
element.is_enabled()  #判断元素是否可用
element.is_selected()  #判断元素是否被选中,可用于单选框和复选框的选项
print(element.get_attribute("outerHTML"))  #可以打印被定位的element的代码
from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.maximize_window()  #最大化窗口
time.sleep(3)

element = driver.find_element_by_id("kw") #定位百度搜索框
print(element.get_attribute("outerHTML"))  #打印元素代码

element.send_keys("python")  #在百度搜索框输入python
driver.find_element_by_id("su").click() #再点击百度一下
time.sleep(3)
print(driver.title)  #打印页面标题
element.clear()   #清空输入框
time.sleep(3)
driver.quit()

selenium rrmoteserver起什么作用 selenium的功能与作用_属性值_05

六、鼠标事件

在测试中除了简单的click()点击鼠标左键的操作,还会涉及到点击鼠标右键,双击鼠标左键等操作,webdriver中使用ActionChains()类来提供鼠标相关操作。ActionChains()提供鼠标事件的常用方法:

  • click(element):单击鼠标左键
  • double_click(element):双击鼠标左键
  • click_and_hold(element):长按鼠标左键
  • context_click(element):单击鼠标右键
  • drag_and_drop(source,target):把元素拖拽到目标元素上然后松开
  • drag_and_drop_by_offset(source,x,y):把元素拖拽到(x,y)位置
  • move_by_offset(x,y):把鼠标移动到(x,y)位置
  • move_to_element(element):把鼠标移到元素位置
  • move_to_element_by_offset(element,x,y):把鼠标移动到距离元素多少距离的位置
  • release(element):在某个元素位置松开鼠标左键
  • perform():执行链中的所有操作

在使用ActionChains之前需要导入类from selenium.webdriver.common.action_chains import ActionChains

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains  #导入鼠标操作类
import time

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.maximize_window()  #最大化窗口
time.sleep(3)

setting = driver.find_element_by_id("s-usersetting-top")  #定位右上角设置菜单
ActionChains(driver).move_to_element(setting).perform()  #鼠标悬停在设置菜单上,显示出子菜单选项
gs = driver.find_element_by_link_text("高级搜索")  #定位子菜单上的高级搜索
gs.click()  #点击高级搜索

time.sleep(3)
driver.quit()  #关闭浏览器

七、键盘事件

有时我们在测试中需要使用tab键将标点聚焦到下一个元素,用于验证元素的排序是否正确;webdriver中的Keys()类提供键盘上的所有键输入,甚至可以模拟一些组合键操作,例如ctrl+a等;在某些复杂情况还会使用send_keys()来模拟上下键操作下拉列表的情况。

使用Keys()类来模拟键盘操作:

  • send_keys(Keys.BACK_SPACE):删除键Backapace
  • send_keys(Keys.SPACE):空格键Space
  • 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,"v"):粘贴ctrl+v
  • send_keys(Keys.CONTROL,"x"):剪切ctrl+x
  • send_keys(Keys.F1):按F1
  • send_keys(Keys.F12):按F12
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.maximize_window()  #最大化窗口
time.sleep(3)

element = driver.find_element_by_id("kw") #定位百度搜索框
element.send_keys("python")  #在搜索框中输入python
element.send_keys(Keys.ENTER) #在搜索框中回车

time.sleep(3)
driver.quit()

八、二次定位

1.二次定位:先定位父元素再定位其子孙元素

selenium rrmoteserver起什么作用 selenium的功能与作用_属性值_06

from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.maximize_window()  #最大化窗口
time.sleep(3)

e1 = driver.find_element_by_id("s-top-left")  #先定位父元素左上方导航栏
# e1.find_elements_by_tag_name("a")[1].click()  #定位导航栏的子元素,在父元素的代码找a标签返回一个列表,取第二个hao123
# e1.find_element_by_css_selector("a:nth-child(2)").click()  #二次定位使用css
e1.find_element_by_xpath("./a[2]").click()   #二次定位使用xpath要写.表示e1元素,再根据e1元素找子元素,写//会在全页面里找

time.sleep(3)
driver.quit()

2.使用select二次定位,只能select下拉框使用

selenium rrmoteserver起什么作用 selenium的功能与作用_css_07

from selenium import webdriver
from selenium.webdriver.support.select import Select  #导入Select
import time

driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/documentation/en/")  #国外网站selenium,加载很慢,加载完成后才开始进行下步操作
driver.maximize_window()  #最大化窗口
time.sleep(3)

s = driver.find_element_by_id("select-language")  #首先定位到select元素
# s.find_elements_by_tag_name("option")[5].click()  #使用二次定位定位option元素
# Select(s).select_by_index(5)  ##根据索引选择,从0开始
# Select(s).select_by_value("https://www.selenium.dev/documentation/zh-cn/") #根据value属性选择
Select(s).select_by_visible_text("中文简体")  #根据文本内容选择,不需要click()

time.sleep(3)
driver.quit()

九、页面操作

1.滚动条操作

在HMTL中有些元素是动态加载的,元素根据滚动条的下拉而被加载;通过JS脚本来控制滚动条

设置JS脚本控制滚动条:js = "window.scrollTo(0,1000)",前面的0是水平距离,1000是垂直距离,单位是像素

selenium同步执行js脚本:driver.execute_script(js)

from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
time.sleep(3)

js = "window.scrollTo(document.body.scrollWidth,0)"  #水平滚动条拉到最右边,document.body.scrollWidth表示实际宽度,也可以写一个足够大的数字
#js = "window.scrollTo(0,document.body.scrollHeight) #垂直滚动到最底部,document.body.scrollHeight表示实际高度
driver.execute_script(js)

time.sleep(3)
driver.execute_script("window.scrollTo(0,0)")  #水平滚动条拉到最左边,第一个数字写0
time.sleep(3)
driver.quit()

2.聚焦元素

滚动条滚动到元素位置,js代码,js = "arguments[0].scrollIntoView();"

from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
time.sleep(3)

setting = driver.find_element_by_id("s-usersetting-top")  #定位右边的设置菜单
driver.execute_script("arguments[0].scrollIntoView();",setting)  #执行js脚本滚动到设置的位置

time.sleep(3)
driver.quit()

3.frame

在web应用中经常用到表单嵌套页面,frame标签有frameset、frame、iframe三种,frameset与其他元素一样,不会影响到定位;而frame和iframe需要切换进去才能定位到其中的元素。通过switch_to_frame()(也可以写switch_to.frame())方法把当前定位的主体切换到表单内嵌页面中。再要定位frame外面的邮箱,需要再切换到外层

#iframe
#网易邮箱
from selenium import webdriver
import time 

driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://mail.163.com/")

iframe = driver.find_element_by_css_selector("div#loginDiv>iframe")  #定位到iframe
driver.switch_to_frame(iframe)  #切换到iframe
email = driver.find_element_by_css_selector("div#account-box>div>input")  #定位到邮箱地址输入框
print(email.get_attribute("outerHTML"))

# driver.switch_to_default_content() #切换到最外层,也可以写driver.switch_to.default_content()
driver.switch_to.parent_frame()  #切换到上一层,如果只有一层frame,这两个操作都可以

e = driver.find_element_by_link_text("企业邮箱")  #定位外层的企业邮箱链接
print(e.get_attribute("outerHTML"))

driver.quit()

4.多窗口切换

在页面中点击每个元素会弹出新的窗口,这时需要切换到新窗口操作

  • switch_to.window():在不同窗口切换,也可以写switch_to_window()
  • current_window_handle:获得当前的窗口句柄
  • window_handles:获取所有的窗口句柄
#切换窗口
from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
time.sleep(3)
driver.find_element_by_link_text("hao123").click()  #点击hao123页面
handles = driver.window_handles   #获取所有的窗口句柄
print(driver.current_window_handle)  #打印当前窗口句柄,CDwindow-96A0DC2749E8B6E507D72A73872755B7,每次打印的都不一样
print(driver.title)  #打印当前窗口标题,百度一下,你就知道
driver.switch_to_window(handles[1])  #切换窗口
print(driver.title)  #打印当前窗口标题,hao123_上网从这里开始

driver.quit()

5.浏览器自带弹窗

webdriver处理js所生成的alert、confirm、prompt,需要使用switch_to_alert()(也可以写switch_to.alert())去定位到弹框,然后使用text/accept/dismiss/send_keys()进行操作

  • text:alert/confirm/prompt弹框中的文本
  • accept:点击确认按钮
  • dismiss:点击取消按钮,有才能操作
  • send_keys():输入值,有输入框才能操作

6.自定义弹框

由于alert弹框不美观,很多网站都自定义弹框,webdriver使用js处理自定义弹框,利用html dom style对象,有一个display属性,设置元素如何被显示;js = 'document.getElementById("id属性值").style.display="none";';document文档,指整个页面代码

selenium rrmoteserver起什么作用 selenium的功能与作用_标签名_08

#处理自定义弹框
#哔哩哔哩
from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.get("https://www.bilibili.com")
driver.maximize_window()
time.sleep(3)

js = 'document.getElementById("elevator").style.display="none";'  #js脚本不显示id为elevator的元素
driver.execute_script(js)  #执行js脚本

time.sleep(3)
driver.quit()

6.单选框和复选框

单选框radio默认是圆形选框,复选框checkbox默认是方形选框

6.1 radio

先定位选项再点击可以选中

#百度
#单选框
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
#导入鼠标操作类
import time

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.maximize_window()  #最大化窗口
time.sleep(3)

setting = driver.find_element_by_id("s-usersetting-top")  #定位右上角设置菜单
ActionChains(driver).move_to_element(setting).perform()  #鼠标悬停在设置菜单上,显示出子菜单选项
gs = driver.find_element_by_link_text("搜索设置")  #定位子菜单上的高级搜索
gs.click()
time.sleep(3)

s1 = driver.find_element_by_id("s1_1")  #定位搜索框显示单选框的显示
# s1.click()  #已选中再次点击没有取消选中
print(s1.is_selected())  #打印选项是否被选中;True
s2 = driver.find_element_by_id("s1_2")   #定位不显示
s2.click()  #点击不显示
print(s1.is_selected())  #打印选项是否被选中;False
print(s2.is_selected())  #打印选项是否被选中;True

time.sleep(3)
driver.quit()

6.2 checkbox

复选框,如果未选中点击会选中,如果已经选中再次点击会取消选中,所以点击之前要先判断是否选中;

#博客园随笔编辑页面
#复选框
from selenium import webdriver
import time

#因为需要登陆,加载了chorme浏览器的用户数据,获取cookie;但是不能开2个浏览器,会报错,提示“Message: invalid argument: user data directory is already in use”
options = webdriver.ChromeOptions()
options.add_argument("user-data-dir=C:\\Users\\***\\AppData\\Local\\Google\\Chrome\\User Data")
driver = webdriver.Chrome(chrome_options=options)

driver.get("")
print(driver.get_cookies())  #可以获取cookies

driver.maximize_window()  #最大化窗口
time.sleep(3)
#滚动到最底部
js = "window.scrollTo(0,10000)"
driver.execute_script(js)
#定位复选框的上层元素
e = driver.find_element_by_css_selector("[name='高级选项']>div:nth-child(2)>div")
#二次定位所有的复选框元素
boxes = e.find_elements_by_css_selector("input[type='checkbox'")
#需要勾选的2个选项的id
list = ["displayOnHomePage","isPinned"]
for box in boxes:
    #复选框会有默认选项,判断是否已选中,如果已选中,反选取消选中
    if box.is_selected():
        box.click()
    #获取元素的id属性,如果是要勾选的,点击勾选
    if box.get_attribute("id") in list:
        box.click()

time.sleep(3)
driver.quit()

7.富文本操作

富文本是一个iframe,需要切换到frame再操作内嵌元素

selenium rrmoteserver起什么作用 selenium的功能与作用_属性值_09

8.文件上传

8.1 一般文件上传是<input type=file ...>,先定位到元素,再send_keys(文件地址)上传文件

selenium rrmoteserver起什么作用 selenium的功能与作用_标签名_10

uploadfile = driver.find_element_by_name("UploadFile")
uploadfile.send_key("文件地址")
time.sleep(n)

上传文件的注意事项:在上传文件的时候需要对文件的类型、大小等做充分的验证;在执行上传脚本时,加一定的等待时间,sleep

8.2 少数上传文件不是input标签,需要借助autoit工具或者SendKeys第三方库解决

https://www.jianshu.com/p/fba37cc5d5e2

9.文件下载

文件下载可以通过加载浏览器配置,也可以自行设置下载的配置项,下面介绍的是设置下载的配置项的方法

9.1Firefox文件下载

#Firefox下载文件
from selenium import webdriver
import time
import os
#通过FirefoxProfile()对其参数做设置,这些参数可以通过在Firefox浏览器地址栏输入:about:config进行设置
fp = webdriver.FirefoxProfile()
fp.set_preference("browser.download.folderList",2) #0表示下载到桌面,1表示下载到默认下载地址,2表示自定义下载路径
fp.set_preference("browser.downlaod.manager.showWhenStarting",False) #在开始下载时是否显示下载管理器
fp.set_preference("browser.download.dir",os.getcwd())  #指定下载路径,os.getcwd()返回当前目录
fp.set_preference("browser.helperApps.never.saveToDisk","application/octet-stream") #不再弹框询问文件类型,application/octet-stream表示二进制流,不知道文件类型;HTTP content-type常用对照表
driver = webdriver.Firefox(firefox_profile=fp)

driver.get("http://chromedriver.storage.googleapis.com/index.html?path=87.0.4280.88/")
time.sleep(3)
driver.find_element_by_xpath('//a[text()="chromedriver_win32.zip"]').click()
time.sleep(5)
driver.quit()

9.2 chrome文件下载

#chrome浏览器文件下载
from selenium import webdriver
import time

options = webdriver.ChromeOptions()
prefs = {
    "profile.default_content_settings.popups":0,  #设置0表示禁止弹出弹框
    "download.default_directory":"E:\\"   #设置文件下载地址
}
options.add_experimental_option("prefs",prefs)
driver = webdriver.Chrome(chrome_options=options)
driver.get("http://chromedriver.storage.googleapis.com/index.html?path=87.0.4280.88/")
time.sleep(3)
driver.find_element_by_xpath('//a[text()="chromedriver_win32.zip"]').click()
time.sleep(5)
driver.quit()

10.截图

#截图
from selenium import webdriver
import time
import os

driver = webdriver.Chrome()
driver.maximize_window()
driver.get("http://www.baidu.com")
time1 = time.strftime("%Y_%m_%d_%H_%M_%S",time.localtime())
filename = time1 + ".png"
path = os.path.abspath("screenshot")
pathname = path + "\\"+filename
# driver.save_screenshot(filename) #截图保存在当前目录,文件名为当时时间
# driver.save_screenshot(pathname) #截图保存在screenshot目录,文件名为当前时间
driver.get_screenshot_as_file(pathname)  #另一种截图保存方法
driver.quit()

十、浏览器免登陆

现在web应用登陆时,通常需要输入验证码,自动化测试时怎么处理验证码:

  • 测试环境让开发去掉验证码
  • 设置一个万能验证码
  • 验证码识别技术
  • 获取cookie免登陆;需要先登陆网站且不能退出,退出cookie会失效

下面介绍通过cookie绕过验证码

1.浏览器加载配置

通过加载浏览器配置可以获取浏览器的cookie信息,绕过登陆

1.1 Firefox

  • 获取Firefox的配置文件路径:菜单>帮助>故障排除信息>配置文件夹;profile_directory=配置文件夹
  • 加载配置文件
profile = FirefoxProfile(profile_directory)
driver = webdriver.Firefox(profile)

1.2 Chrome

options = webdriver.ChromeOptions()
options.add_argument("user-data-dir=C:\\Users\\***\\AppData\\Local\\Google\\Chrome\\User Data")  #只能打开一个chrome浏览器不然会报错
driver = webdriver.Chrome(chrome_options=options)

 2.通过cookie

driver.get_cookies():获取所有的Cookie,返回列表格式,列表里面套字典

driver.get_cookie(name):获取指定name的Cookie值

driver.add_cookie(dict):添加cookie,必须要有name和value

driver.delete_cookie(name):删除指定name的cookie

driver.delete_all_cookie():删除所有的Cookie

#cookie登录博客园
from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.maximize_window()  #最大化屏幕
driver.get("")  #进入博客园页面
time.sleep(5)
#cookies登录博客园
cookies = [{'domain': '.cnblogs.com', 'expiry': 1611398938, 'httpOnly': False, 'name': '_gat_gtag_UA_48445196_1', 'path': '/', 'secure': False, 'value': '1'}, 
{'domain': 'i.cnblogs.com', 'httpOnly': True, 'name': '.AspNetCore.Session', 'path': '/', 'secure': False, 'value': 'C***'}, 
{'domain': '.cnblogs.com', 'expiry': 1611485278, 'httpOnly': False, 'name': '_gid', 'path': '/', 'secure': False, 'value': '**'}, 
{'domain': '.cnblogs.com', 'expiry': 1671607788, 'httpOnly': False, 'name': '_ga_4CQQXWHK3C', 'path': '/', 'secure': False, 'value': 'G**'}, 
{'domain': '.cnblogs.com', 'expiry': 1674470878, 'httpOnly': False, 'name': '_ga', 'path': '/', 'secure': False, 'value': 'GA**'},
 {'domain': '.cnblogs.com', 'expiry': 1634994906, 'httpOnly': False, 'name': '__gads', 'path': '/', 'secure': False, 'value': 'ID**'},
 {'domain': '.cnblogs.com', 'expiry': 1619531791, 'httpOnly': False, 'name': 'UM_distinctid', 'path': '/', 'secure': False, 'value': '**'},
 {'domain': '.cnblogs.com', 'expiry': 1612672030, 'httpOnly': True, 'name': '.Cnblogs.AspNetCore.Cookies', 'path': '/', 'secure': False, 'value': '**'},
 {'domain': '.cnblogs.com', 'expiry': 1632998446, 'httpOnly': False, 'name': 'Hm_lvt_39b794a97f47c65b6b2e4e1741dcba38', 'path': '/', 'secure': False, 'value': '160***'}]
for cookie in cookies:
    driver.add_cookie(cookie)
time.sleep(3)
driver.refresh() #刷新浏览器,不刷新页面是看不到登陆后的信息的
time.sleep(3)
driver.find_element_by_id("user_icon").click()  #点击右上方图像进入个人博客主页
time.sleep(5)
print(driver.title)  #打印现在的页面标题,小测试00的主页 - 博客园
driver.quit()

十一、元素等待

由于现在大多数web应用程序都结合Ajax/JavaScript技术开发,当浏览器进行页面信息加载时,页面中的元素会在不同的时间间隙陆续完成加载;还有网络、电脑配置、服务器反应时间等因素影响,为了保证脚本的稳定性,需要给脚本增加一定的等待时间。

1.强制等待

time.sleep(s):针对Python代码,强制等待;有时控件加载或2个操作之间会sleep,防止网站认为是爬虫

2.隐式等待

driver.wait_implicatly(s):webdriver会在DOM中查找该元素,如果没找到将继续等待,超出设置的等待最大时间后将抛出找不到元素的异常。隐式等待服务于当前的整个测试脚本。

from selenium import webdriver
import time

driver = webdriver.Chrome()
print(time.time())
driver.implicitly_wait(10)   #隐式等待
driver.get("https://github.com/")
print(time.time())
element = driver.find_element_by_partial_link_text("Sign up")  #查找一个存在的元素
print(element.get_attribute("outerHTML"))
print(time.time())
try:
    element1 = driver.find_element_by_tag_name("canvas1")  #查找一个不存在的元素
except Exception as e:
    print(e)
print(time.time())
driver.quit()

3.显示等待

WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)在设定时间内等待指定元素,超出最长等待时间则抛出错误:

  • driver:浏览器驱动
  • timeout:最长等待时间,默认单位为秒
  • poll_frequency:监测隔间时间,默认为0,5s
  • ignored_exceptions:忽略的报错信息
  • WebDriverWait有until和until_not方法;until(method,message);until_not(method,message)
#显示等待
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait

driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
element = WebDriverWait(driver,10).until(lambda x:x.find_element_by_id("kw"))  #until参数必须是一个方法,不能直接用driver.find_element;找一个存在的元素,找到返回元素,不存在报错
print(element.get_attribute("outerHTML"))
element_is_displayed = WebDriverWait(driver,10).until(lambda x:x.find_element_by_id("kw").is_displayed()) #一个元素是否可见,返回布尔值
print(element_is_displayed)
try:
    element = WebDriverWait(driver,10).until(lambda x:x.find_element_by_id("kk"),"没找到元素")  #找一个不存在的元素
    print(element.get_attribute("outerHTML"))
except Exception as e:
    print(e)
driver.quit()

selenium rrmoteserver起什么作用 selenium的功能与作用_标签名_11

 

selenium rrmoteserver起什么作用 selenium的功能与作用_标签名_12

4.expected_conditiions

expected_conditions是selenium的一个模块(简称EC),其中包含一系列可用于判断的条件;EC返回的是方法,常和WebDriverWait配合使用:

  • title_is(title):判断网页title是否是括号内文本,返回布尔值
  • title_contains(title):判断网页title是否包含文本,返回布尔值
  • url_to_be(url):网页网址是否完全等于指定url,返回布尔值
  • url_coantains(url):网页网址是否包含指定内容,返回布尔值
  • url_matches(url):网页网址是否匹配指定内容,返回布尔值
  • presence_of_element_located(locator):判断一个元素是否存在于页面DOM数中,存在则返回元素本身,不存在则返回False;locator是一个(by,path)元组,表示元素位置
  • presence_of_all_elements_located(locator):定位的元素范围内,是否有一个元素存在于页面DOM中,如果是,返回满足条件的所有元素组成的list,否则返回False
  • visibility_of_element_located(locator):判断一个元素是否存在与页面DOM数中且可见,可见意为元素的高和宽都大于0,存在则返回元素本身,不存在则返回False
  • visibility_of(element):判断element是否可见,是返回元素,不存在返回False
  • visibility_of_any_elements_located(locator):判断是否至少有一个元素在页面中可见,是返回列表
  • invisibility_of_element_located(locator):判断一个元素是否不可见或者不存在页面DOM中,不存在则返回True,
  • element_to_be_clickable(locator):判断一个元素是否可见并可点击,如果可以则返回该元素,否则返回False
  • element_to_be_selected(element):判断一个元素是否已选择,是返回True
  • text_to_be_present_in_element(locator,text):判断一个元素的文本是否包含text,返回布尔值
  • text_to_be_present_in_element_value(locator,text):判断一个元素的属性值中是否包含text,返回布尔值
  • frame_to_be_available_and_switch_to_it(locator):判断一个frame是否可以切换,如果可以切换frame并且返回True,否则返回False
  • staleness_of(element):等待一个元素从页面DOM中消失,如果元素一直存在返回False,否则返回True
  • alert_is_present():判断页面上是否有弹窗,如果存在返回弹框,如果不存在返回False
#WebDriverWait and excepted_conditions
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
t1 = EC.title_is("百度一下,你就知道")
t2 = EC.title_contains("我不知道")
print(t1,"\n",t2)  #打印方法
print(t1(driver),"\n",t2(driver))  #打印布尔值
locator = (By.CLASS_NAME,"s_ipt") #使用By定位的写法,需要先导入By,定位方式全大写
locator2 = ("class name","s_ipt") #不需要导入By,用下划线连接的名称变为空格分开
e1 = EC.presence_of_element_located(locator2)  #一个页面上存在的元素
print(e1)  #打印方法
print(e1(driver))  #打印元素
try:
    e2 = EC.presence_of_element_located((By.CLASS_NAME,"s_ipt11"))
    print(e2)
    print(e2(driver))
except Exception as e:
    print(e)
e3 = WebDriverWait(driver,10).until(EC.presence_of_element_located(("class name","s_ipt")))
print(e3)  #打印元素
driver.quit()

selenium rrmoteserver起什么作用 selenium的功能与作用_css_13