首页 > 技术文章 > Selenium-WebDriver原理,属性,方法

doupi 2020-09-18 01:43 原文

WebDriver工作原理

  1. 对于每一条Selenium脚本,一个http请求会被创建并发送给浏览器的驱动
  2. 浏览器驱动轴包含了一个HTTP Server,用来接收这些http请求
  3. HTTP Server接收到请求后根据请求来具体操控对应的浏览器
  4. 浏览器执行具体的测试步骤
  5. 浏览器将步骤执行结果返回给HTTP Server
  6. HTTP Server又将结果返回给Selenium的脚本,如果是错误的http代码我们就会在控制台看到对应的报错信息

WebDriver的协议

  • WebDriver使用的协议是:JSON Wire protocol
  • 通信的数据格式是JSON

WebDriver的属性

属性 属性描述
driver.name 浏览器名称
driver.current_url 当前url
driver.title 当前页面标题
driver.page_source

当前页面源码

driver.current_window_handle 窗口句柄(相当于一个tab)
driver.window_handles 当前窗口所有句柄

WebDriver方法

方法 方法描述
driver.back() 浏览器后退
driver.forward() 浏览器前进
driver.fresh() 浏览器刷新
driver.close() 关闭当前窗口
driver.quit() 退出浏览器
driver.switch_to.frame() 切换到frame
driver.switch_to.alert 切换到alert
driver.switch_to.active_element 切换到活动元素
driver.switch_to.window 切换窗口

WebElement属性

当我们使用WebDriver的find方法定位到元素后,会返回一个WebElement对象,该对象用来描述Web页面上的一个元素.WebElement的常用属性和方法见下表

属性 属性描述
id 标识
size 宽高
rect 宽高和坐标
tag_name 标签名称
text 文本内容

WebElement方法

方法 方法描述
send_keys() 输入内容
clear() 清空内容
click() 单击
get_attribute() 获得属性值
is_selected() 是否被选中
is_enabled() 是否可用
is_displayed() 是否显示
value_of_css_property() css属性值

操作下拉列表

处理下拉列表,需要用到selenium中的一个工具类Select,工具位置 from selenium.webdriver.support.select import Select,使用方法

    def test_select(self):
        se = self.driver.find_element_by_id('province')
        select =Select(se)
        select.select_by_index(2)
        sleep(2)
        select.select_by_value('bj')
        sleep(2)
        select.select_by_visible_text('上海')

select常见方法

方法/属性 描述
select_by_value() 根据源码value选择
select_by_index() 根据索引选择 
select_by_visible_text() 根据文本选择
deselect_by_value() 根据源码value反选
deselect_by_index() 根据索引反选
deselect_by_visible_text() 根据文本反选
deselect_all 反选所有
options 返回包含所有选项的列表
all_selected_options 所有已选中选项
first_selected_option 第一个选择选项

处理弹框

页面上的弹框有三种

  • alert:用来提示
  • confirm:用来确认
  • prompt:输入内容
方法/属性 描述
accept() 接受
dismiss() 取消
text 弹框的文本
send_keys 输入内容

selenium的三种等待方式

  • time.sleep(sec) 固定等待,不推荐实际测试时使用,可以用来调试
  • implicitly_wait  如果某些元素不是立即可用的,隐式等待是告诉WebDriver去等待一定的时间后去查找元素。默认等待时间是0秒,一旦设置该值,隐式等待是设置该WebDriver的实例的生命周期
  • WebDriverWait 显式等待是你在代码中定义等待一定条件发生后再进一步执行你的代码,推荐用此方法

显式等待使用方法

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
def test_wait(self):
wait = WebDriverWait(self.driver, 2)
wait.until(expected_conditions.title_contains('百度一下'))
self.driver.find_element_by_id('kw').send_keys('selenium')

WebDriverWait参数:

  • driver:传入WebDriver实例,即我们上例中的driver
  • timeout:超时时间,等待的最长时间
  • poll_frequency:调用until或until_not中的方法的间隔时间,默认是0.5秒
  • ignored_exceptions:忽略的异常,如果在调用until或until_not的过程中抛出这个元组中的异常,则不中断代码,继续等待,如果抛出的是这个元组外的异常,则中断代码,抛出异常。默认只有NoSuchElementException。

这个模块中,一共只有两种方法 until 与 until_not:

  • until:当某元素出现或什么条件成立则继续执行
  • until_not:当某元素消失或什么条件不成立则继续执行

until 与 until_not 参数如下:

  • method:在等待期间,每隔一段时间调用这个传入的方法,直到返回值不是False
  • message:如果超时,抛出TimeoutException,将message传入异常

WebDriverWait的17种等待条件

条件 描述 返回值
titile_is 判断title,是否出现 布尔
title_contains 判断title,是否包含某些字符 布尔
presence_of_element_located

判断某个元素是否被加到了dom树里,

并不代表该元素一定可见

WebElement
visibility_of_element_located

判断某个元素是否被加到了dom树里,

并且可见,宽和高都大于0

WebElement
visibility_of 判断元素是否可见,如果可见就返回这个元素 WebElement
presence_of_all_element_located 判断是否至少有1个元素存在于dom树中 列表
visibility_of_any_element_located 判断是否至少有1个元素在页面中可见 列表
text_to_be_present_in_element 判断指定的元素中是否包含了预期的字符串 布尔
text_to_be_present_in_element_value

判断指定元素的属性值中是否包含了预期的

字符串

布尔
frame_to_be_available_and_switch_to_it 判断frame是否可以switch进去 布尔
invisibility_of_element_located 判断某个元素是否存在于dom或不可见 布尔
element_to_be_clickable 判断某个元素中是否可见并且是enable的,代表可点击 布尔
staleness_of 等待某个元素从dom树中移除 布尔
element_to_be_selected 判断某个元素是否被选中了,一般用在下拉列表 布尔
element_selection_state_to_be 判断某个元素的选中状态是否符合预期 布尔
element_located_selection_state_to_be 判断某个元素的选中状态是否符合预期 布尔
alert_is_present 判断页面上是否存在alert alert

Selenium鼠标和键盘事件

selenium中的鼠标和键盘事件被封装在ActionChains类中,正确的使用方法是:

ActionChains(driver).click(button).perform()

ActionChains常用方法:

方法 方法描述
click(on_element=None) 点击鼠标左键
click_and_hold(on_element=None) 点击鼠标左键,不松开
context_click(on_element=None) 点击鼠标右键
double_click(on_element=None) 点击鼠标左键
drag_and_drop(source,target) 拖拽到某个元素然后松开
drag_and_drop_by_offset(source,xoffset,yoffset) 拖拽到某个坐标然后松开
key_down(value,element=None) 按下键盘上的某个键
key_up(value,element=None) 松开某个键
move_by_offset(xoffset,yoffset) 鼠标送当前位置移动到某个坐标
move_to_element(to_element) 鼠标移动到某个元素
move_to_element_with_offset(to_element,xoffset,yoffset) 移动到某个元素(左上角坐标)多少距离的位置
perform() 执行链中所有动作
release(on_element=None) 在某个元素位置松开鼠标左键
send_keys(*keys_to_send) 发送某个键到当前焦点的元素
send_keys_to_element(element,*keys_to_send) 发送某个键到指定元素

代码演示

   def test_mouse(self):
        btn=self.driver.find_element_by_xpath('/html/body/form/input[2]')
        #双击
        ActionChains(self.driver).double_click(btn).perform()
        sleep(2)
        btn = self.driver.find_element_by_xpath('/html/body/form/input[3]')
        #单击
        ActionChains(self.driver).click(btn).perform()
        sleep(2)
        btn = self.driver.find_element_by_xpath('/html/body/form/input[4]')
        #右击
        ActionChains(self.driver).context_click(btn).perform()
        sleep()

    def test_key(self):
        self.driver.get('http://www.baidu.com')
        kw=self.driver.find_element_by_id('kw')
        kw.send_keys('selenium')
        #按下control+a全选
        kw.send_keys(Keys.CONTROL,'a')
        sleep(2)
        # 按下control+x剪切
        kw.send_keys(Keys.CONTROL,'x')
        sleep(2)
        # 按下control+v粘贴
        kw.send_keys(Keys.CONTROL,'v')
        sleep(2)

Selenium屏幕截图

WebDriver内置了一些在测试中捕获屏幕并保存的方法

方法 方法描述
save_screenshot(filename) 获取当前屏幕截图并保存当当前目录
get_screenshot_as_base64() 获取当前屏幕截图base64编码字符串
get_screenshot_as_file(filename) 获取当前的屏幕截图,使用完整的路径
get_screenshot_as_png() 获取当前屏幕截图的二进制文件数据

代码示例

    def test(self):
        self.driver.find_element_by_id('kw').send_keys('selenium')
        self.driver.find_element_by_id('su').click()
        sleep(2)
        self.driver.get_screenshot_as_file('d:/baidu.png')
        self.driver.quit()

Selenium定位frame ifame

frame标签有frameset,frame,iframe三种,framset跟其他普通标签没有区别,不会影响到正常的定位,而frame与iframe堆selenium定位而言是一样的,selenium有一组方法对frame进行操作.

方法 方法描述
switch_to_frame(reference)

切换frame,,reference是传入的参数,用来定位frame,可以传入id,name,index

以及selenium的WebDriver对象

switch_to.default_content() 返回主文档
switch_to.parent_frame() 返回父文档

 时间控件操作

通过js脚本实现

driver.get("https://www.12306.cn/index/")
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("2020-10-16")

 

推荐阅读