web常用自动化库——selenium总结(转)

 

 

概述

selenium是一个模拟控制浏览器操作的自动化库,它可以做到元素定位,鼠标事件,浏览器事件,js脚本执行等操作

与request不同的是,request是单独请求一个http,而selenium则是以浏览器方式加载整个页面流,所以那些异步的请求也不用像request一样去分析接口,一切都像浏览器一样,所见即所得。

优点是:

1.所见即所得,不用考虑cookie,ajax,重定向等等,方便数据的查取

2.平时在我们在浏览器上做的操作(鼠标,浏览器操作等),基本都可以用这个实现,并且步骤动态可视

3.多平台支持,不仅语言多平台支持,支持浏览器driver也很多

缺点是:

1.慢,由于加载了整个页面的数据流,资源开销大,所以对于只想获取关键数据来说肯定没有请求接口来的快

2.不稳定,脚本维护成本高等,比如你用xpath去找元素,但是前端改其他问题影响到了你这个元素的路径,那么这个脚本就gg

主要作用:

1.用于前端自动化测试,总的来说算集成测试,更关注用户端的测试

2.模拟登录等,爬虫的模拟登录常用到,同时使用这种时要开开发者模式,因为已经有很多网站能识别了

3.个人办公用途,减少重复劳动力。举个栗子:百度云离线下载多个链接

 

安装

库安装

pip install selenium

WebDriver安装

WebDriver是W3C的一个标准,由Selenium主持,主要目的就是通过这套WebDriverAPI控制你电脑上的浏览器,相当于一个selenium与浏览器之间的驱动,需要注意的是,不同浏览器,需要安装不同的WebDriver,常见的如下

Firefox浏览器 https://github.com/mozilla/geckodriver/releases
Chrome浏览器 https://sites.google.com/a/chromium.org/chromedriver/downloads
IE浏览器 http://selenium-release.storage.googleapis.com/index.html
Edge浏览器 https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
Opera浏览器 https://github.com/operasoftware/operachromiumdriver/releases
PhantomJS浏览器 https://phantomjs.org/

其中PhantomJS是一个无窗口的WebDriver,现在已经停更了

根据你电脑所装浏览器版本来安装WebDriver(至少需要大版本相同,不然会有一些问题),安装WebDriver很简单,将可执行文件放到脚本目录或者python安装目录即可

 

WebDriver

创建WebDriver对象

创建WebDriver对象,相当于启动了浏览器

web常用自动化库——selenium总结(转)
#导入webdriver模块
from selenium import webdriver

#创建对象,根据你选择的浏览器创建

driver = webdriver.Chrome()
driver = webdriver.Firefox()
driver = webdriver.Ie()
driver = webdriver.Edge()
driver = webdriver.Opera()
driver = webdriver.PhantomJS()
web常用自动化库——selenium总结(转)

 

WebDriver对象操作

对WebDriver对象的操作可以抽象成你怎么去控制浏览器,主要方法有:

1.访问URL

driver.get("http://www.python.org")

2.窗口大小调整

#设置宽800px 高600px
driver.set_window_size(800,600)

#设置最大,最小
driver.maximize_window()
driver.minimize_window()

3.刷新页面

driver.refresh()

4.前进后退

driver.forward()
driver.back()

5.关闭浏览器或窗口

#关闭浏览器
driver.quit()
#关闭窗口
driver.close()

6.返回当前的一些属性

web常用自动化库——selenium总结(转)
#当前url
driver.current_url
#返回窗口句柄
driver.current_window_handle  #当前
driver.window_handles #所有
#返回title
driver.title
web常用自动化库——selenium总结(转)

7.查找元素,返回Element对象,之后会详细讲

web常用自动化库——selenium总结(转)
find_element_by_name()
find_element_by_id()
find_element_by_xpath()
find_element_by_link_text()
find_element_by_partial_link_text()
find_element_by_tag_name()
find_element_by_class_name()
find_element_by_css_selector()
web常用自动化库——selenium总结(转)

8.切换窗口

driver.switch_to_window(handle)

9.切换frame

#切换框架,直接输入iframe的name或id属性,或者传入定位的元素
driver.switch_to_frame(frame_reference)

10.截图保持为文件

#img_path_name为文件路径,只支持.png格式,文件名注意带上后缀,如“/Screenshots/foo.png”
driver.get_screenshot_as_file(img_path_name)

11.执行js

web常用自动化库——selenium总结(转)
#简单执行
driver.execute_script(script, *args)
    -script:要执行的JavaScript。
    -*args:JavaScript的所有适用参数。

#异步执行
driver.execute_async_script(script, *args)
web常用自动化库——selenium总结(转)

12.操作cookie

web常用自动化库——selenium总结(转)
#获取cookies
driver.get_cookies()

#添加cookie
driver.add_cookie(cookie_dict) 

#删除cookie
driver.delete_all_cookies()  #所有
driver.delete_cookie(name) #一个,指明key
web常用自动化库——selenium总结(转)

 

元素Element

查找元素Element

在我们使用driver.get(url)方法后,driver会加载整个页面,如果我们要操作比如点击页面中的某个元素,则首先需要定位到这个元素,再进行操作

注意的是这部分需要HTML CSS XPATH基础,不熟悉的可以查看W3C教程,这里不做多诉

示例

web常用自动化库——selenium总结(转)
<html>
 <body>
  <h1>Welcome</h1>
  <p class="content">Site content goes here.</p>
  <form id="loginForm">
   <input name="username" type="text" />
   <input name="password" type="password" />
  </form>
  <a href="continue.html">Continue</a>
</body>
<html>
web常用自动化库——selenium总结(转)

1.通过id属性定位

driver.find_element_by_id(‘loginForm’)

#定位<form id="loginForm">

2.通过name属性定位

driver.find_element_by_name(‘username’)

#定位<input name="username" type="text" />

3.通过class名定位

driver.find_elements_by_class_name(‘content’)

#定位<p class="content">Site content goes here.</p>

4.通过TagName标签名定位

driver.find_element_by_tag_name(‘input’)

#定位<input name="username" type="text" />,如果匹配了多个,只选第一个

5.通过link text定位,就是通过a标签的text内容定位

driver.find_elements_by_link_text(‘Continue’) #全匹配 
driver.find_element_by_partial_link_text(‘Cont’) #部分text匹配

#定位<a href="continue.html">Continue</a>

6.通过xpath定位

driver.find_element_by_xpath("//from[input/@name=‘username‘]")

#定位<input name="username" type="text" />

 简单说一句:/ 代表选取直接子节点,// 代表选择所有子孙节点,. 代表选取当前节点,.. 代表选取当前节点的父节点,@ 则是加了属性的限定并选取匹配属性的特定节点,[]是谓语的意思。

7.通过css选择器定位

driver.find_element_by_css_selector(‘p.content‘)

#定位<p class="content">Site content goes here.</p>

8.定位多个元素

将1~7中的find_element_by_xxx改成find_elements_by_xxx则可以返回所有匹配的元素为list

driver.find_elements_by_tag_name(‘input’)

定位[<input name="username" type="text" />
   <input name="password" type="password" />]

9.串联查找

Element对象也是有find_element_by_xxx这些方法的,所以可以在第一次定位的元素下查找子节点等

driver.find_element_by_id(‘loginForm’).find_element_by_name(‘username’)

10.简洁方法

find_element(by=‘id‘, value=None)与find_elements(by=‘id‘, value=None)实际是实现find_element_by_xxx这个的底层实现,只是简洁些,当然我们也可以用

#导入By模块,实际里面就是id,class,name这些常量
from selenium.webdriver.common.by import By

driver.find_element(By.NAME,username)

 

元素Element事件

Element对象有一系列的方法,来让我们操作定位的元素

1.Element.click() 点击元素

driver.find_elements_by_link_text(‘Continue’).click()

2.输入文本

#有些输入框中原有的文本不会被自动清除掉,需要使用clear()方法清除
driver.find_element_by_name(‘username’).clear()

#输入内容
driver.find_element_by_name(‘username’).send_keys("username")

3.获取参数

web常用自动化库——selenium总结(转)
#获取对应特性值
Element.get_attribute(name)

#获取对应属性值
Element.get_property(name)

#property是DOM中的属性,是JavaScript里的对象;attribute是HTML标签上的特性,它的值只能够是字符串。一般用attr就行

#获取当前元素的内容
Element.text

#获取当前元素标签名
Element.tag_name

#获取当前元素尺寸
Element.size

#获取当前元素坐标
Element.location
web常用自动化库——selenium总结(转)

4.判断方法

web常用自动化库——selenium总结(转)
#判断当前元素是否可见
Element.is_displayed()

#判断当前元素是否被启用
Element.is_enabled()

#判断当前元素是否被选中
Element.is_selected()
web常用自动化库——selenium总结(转)

 

等待

现在的网页,基本都是使用ajax异步的加载各种资源的,所以可能我们需要定位的元素不会第一时间就加载出来,这时候是无法定位的,也就会抛出异常。而解决这个问题的方法,就是等待。

1.硬性等待

使用time.sleep(sec)实现,需要自己估计网页加载的时间,硬性地等待,无论网页加载快慢,都会强制等待这么多时间

import time

time.sleep(10)

2.显式等待

就是设定一个条件,同时设置一个时间,在这个时间范围内,如果网页出现符合的条件,就不等待继续执行,如果没有则循环直到超时报错

web常用自动化库——selenium总结(转)
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delay_loading")
try:
    element = WebDriverWait(driver,10).until(
        EC.presence_of_element_located((By.ID,"myDynamicElement"))
    )
finally:
    driver.quit()
web常用自动化库——selenium总结(转)

这段代码主要讲的是:

  1. 实例化WebDriverWait类,传入driver与最大等待时长,默认poll_frequency(扫描频率)为500毫秒
  2. until()是WebDriverWait类的一个方法,参数是一个等待条件(expected_conditions),如果满足等待条件,则WebDriverWait类停止等待,并且返回expected_conditions的值,否则当等待时间到将抛出TimeoutException异常
  3. 除了until()还有个until_not(),看语义就明白
  4. 等待条件(expected_conditions)如果成功则返回element对象,或有些是返回布尔值,或者其它不为null的值

等待条件(expected_conditions)内置的方法主要有:

web常用自动化库——selenium总结(转)
title_is : #验证 driver 的 title 是否与传入的 title 一致,返回布尔值
title_contains : #验证 driver 的 title 中是否包含传入的 title,返回布尔值
presence_of_element_located :# 验证页面中是否存在传入的元素,传入元素的格式是 locator 元组,如 (By.ID, "id1"),返回element对象
visibility_of_element_located : #验证页面中传入的元素( locator 元组格式 )是否可见,这里的可见不仅仅是 display 属性非 None ,还意味着宽高均大于0,返回element对象或false
visibility_of : #验证页面中传入的元素( WebElement 格式 )是否可见。返回element对象或false
presence_of_all_elements_located : #验证页面中是否存在传入的所有元素,传入元素的格式是 locator 元组构成的 list,如 [(By.ID, "id1"), (By.NAME, "name1"),返回element或false
text_to_be_present_in_element : #验证在指定页面元素的text中是否包含传入的文本,返回布尔值
text_to_be_present_in_element_value : #验证在指定页面元素的value中是否包含传入的文本,返回布尔值
frame_to_be_available_and_switch_to_it : #验证frame是否可切入,传入 locator 元组 或 WebElement,返回布尔值
invisibility_of_element_located : #验证页面中传入的元素( locator 元组格式 )是否可见,返回布尔值
element_to_be_clickable : #验证页面中传入的元素( WebElement 格式 )是否点击,返回element
staleness_of : #判断传入元素(WebElement 格式)是否仍在DOM中,返回布尔值
element_to_be_selected : #判断传入元素(WebElement 格式)是否被选中,返回布尔值
element_located_to_be_selected :# 判断传入元素(locator 元组格式)是否被选中,返回布尔值
element_selection_state_to_be :# 验证传入的可选择元素(WebElement 格式)是否处于某传入状态,返回布尔值
element_located_selection_state_to_be : #验证传入的可选择元素(WebElement 格式)是否处于某传入状态,返回布尔值
alert_is_present : #验证是否有 alert 出现。返回alert对象
web常用自动化库——selenium总结(转)

3.隐式等待

一种全局的设置,设置一个最大时长,如果定位的元素没有出现就会循环的查询直到超时或者元素出现,相比于硬性等待,这个更加弹性,元素出现了就不会等待了

rom selenium import webdriver

driver = webdriver.Firefox()
driver.implicitly_wait(10) # seconds
driver.get("http://somedomain/url_that_delays_loading")
myDynamicElement = driver.find_element_by_id(‘myDynamicElement‘)

 

行为链

ActionChains可以完成简单的交互行为,例如鼠标移动,鼠标点击事件,键盘输入,以及内容菜单交互。这对于模拟那些复杂的类似于鼠标悬停和拖拽行为很有用

使用方法:

实例化一个ActionChains对象并在对象上调用行为方法时,这些行为会存储在ActionChains对象的一个队列里。只有调用perform()时,这些动作就以他们队列的顺序来触发

导入类

from selenium.webdriver import ActionChains

链式模型操作:

menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")

ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()

队列顺序操作:

web常用自动化库——selenium总结(转)
menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")

actions = ActionChains(driver)
actions.move_to_element(menu)
actions.click(hidden_submenu)
action.perform()
web常用自动化库——selenium总结(转)

主要的行为方法有

web常用自动化库——selenium总结(转)
click(on_element=None)
#点击一个元素。参数:on_element:要点击的元素,如果是None,点击鼠标当前的位置

click_and_hold(on_element=None)
#鼠标左键点击一个元素并且保持。参数:on_element:同click()类似

double_click(on_element=None)
#双击一个元素

drag_and_drop(source, target)
#鼠标左键点击source元素,然后移动到target元素释放鼠标按键

drag_and_drop_by_offset(source, xoffset,yoffset)
#拖拽目标元素到指定的偏移点释放。参数: source:点击的参数 xoffset:X偏移量 * yoffset:Y偏移量

key_down(value,element=None)
#只按下键盘,不释放。我们应该只对那些功能键使用(Contril,Alt,Shift)。参数: value:要发送的键,值在Keys类里有定义 element:发送的目标元素,如果是None,value会发到当前聚焦的元素上

key_up(value,element=None)
#释放键。参考key_down的解释

move_by_offset(xoffset,yoffset)
#将当前鼠标的位置进行移动

move_to_element(to_element)
#把鼠标移到一个元素的中间

move_to_element_with_offset(to_element,xoffset,yoffset)
#鼠标移动到元素的指定位置,偏移量以元素的左上角为基准。参数: to_element:目标元素 xoffset:要移动的X偏移量 * yoffset:要移动的Y偏移量

perform()
#执行所有存储的动作

release(on_element=None)
#释放一个元素上的鼠标按键

send_keys(*keys_to_send)
#向当前的焦点元素发送键

send_keys_to_element(element,*keys_to_send)
#向指定的元素发送键
web常用自动化库——selenium总结(转)

参考的key值在这里

 

弹窗操作

目前主流弹窗就三种,alert,window,div封装的

alert弹窗

alert弹窗主要是js中alert()、confirm()、prompt()方法实现的,虽然这三种在js中不同,但对selenium都可以统一实例化Alert对象处理,首先查看Alert对象的主要方法

web常用自动化库——selenium总结(转)
#接受和忽略弹框:

Alert(driver).accept()
Alert(driver).dismiss()

#prompt里输入字符:

Alert(driver).send_keys("text")

#读取prompt的提示字符:

Alert(driver).text

#向一个认证的对话框发送用户名和密码,会自动点击确认

Alert(driver).authenticate(‘user‘,‘passwd‘)
web常用自动化库——selenium总结(转)

对于弹窗生成Alert对象主要有两种方法

1.使用driver的API切换至弹窗操作

alert = driver.switch_to_alert() #底层实际就是Alert(driver),返回Alert对象

2.直接使用Alert类实例化

from selenium.webdriver.common.alert import Alert

alert = Alert(driver)

window类型

window类型实际就是那种点击界面元素后,浏览器新开的一个窗口,我们可以用driver的API直接切换到这个窗口进行一般的定位元素那些操作

#选择对应的window_handle切换
driver.switch_to_window(window_handle)

#window_handle获取
driver.current_window_handle
driver.window_handles

div封装的

div封装的弹窗就是使用浏览器F12查看HTML源代码时,弹窗的代码由div标签封装在页面中,所以这种弹窗可以直接find_element_by_xxx直接定位

可能还有网页中使用frame标签的,这就需要先切换到新的frame,上面driver的方法有介绍

如果对JavaScript熟悉的,这些弹窗都可以用js处理

 

 

参考:

https://python-selenium-zh.readthedocs.io/zh_CN/latest

https://selenium-python.readthedocs.io/api.html

 

转自:https://www.cnblogs.com/fengf233/p/11635196.html

web常用自动化库——selenium总结(转)

上一篇:git上传提交的时出现:Please tell me who you are


下一篇:配置Nginx反向代理、HTTPS和认证