selenium web控件的交互进阶
Action
ActionChains: 执行PC端的鼠标点击,双击,右键,拖曳等事件
TouchActions: 模拟PC和移动端的点击,滑动,拖曳,多点触控等多种手势操作
动作链接 ActionChains
执行原理:
调用 ActionChains 方法的时候,不会立刻执行,而是将所有的操作放到一个队列里面,当调用 perform() 方法的时候,队列的事件就会依次执行
基本用法:
- 生成一个动作 actions =ActionChains(driver)
- 动作添加方法1 actions.move_to_element(menu)
- 动作添加方法2 actions.click(hidden_submenu)
- 调用 actions.perform() 方法执行
具体写法:
- 链式写法
ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()
- 分布写法
actions =ActionChains(driver)
actions.move_to_element(menu)
actions.click(hidden_submenu)
actions.perform()
ActionChains 具体用法
用法一: 点击,右键,双击操作
actions =ActionChains(driver)
actions.click(element)
actions.double_click(element)
actions.context_click(element)
actions.perform()
测试网站: https://sahitest.com/demo/clicks.htm
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File :test_02.py
@Describe :
@Create :2021/06/23 00:16:26
@Author :od
'''
import pytest
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
class TestActions:
def setup(self):
self.chrome_options = Options()
self.chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") # 指定配置好的 chrom
self.chrome_driver = r"./chromedriver.exe" # 驱动路径
self.driver = webdriver.Chrome(self.chrome_driver, chrome_options=self.chrome_options) # 加入驱动设置
# self.driver.get('https://sahitest.com/demo/clicks.htm') # 发起请求
# self.driver.maximize_window() # 设置为最大化
self.driver.implicitly_wait(3) # 添加一个隐式等待默认等待3秒
def teardown(self):
print('关闭浏览器')
time.sleep(1)
# self.driver.quit()
# 测试用例如果不加sleep的话,元素如果没加载出来,是会报错的,所以我们要加个隐式等待
def test_clicks(self):
print('go')
dbl_click_me = self.driver.find_element_by_xpath("//input[@value='dbl click me']") # 双击
click_me = self.driver.find_element_by_xpath("//input[@value='click me']") # 单击
right_me = self.driver.find_element_by_xpath("// input[ @ value='right click me']") # 右键
action = ActionChains(self.driver) # 初始化
action.click(click_me) # 点击一次
action.double_click(dbl_click_me) # 双击两次
action.context_click(right_me) # 右键一次
action.perform() # 启动
if __name__ == '__main__':
pytest.main(['-vs', "test_action.py::TestActions"])
用法2
鼠标移动到某个元素上面
action = ActionChains(self.driver)
action.move_to_element(element)
action.perform()
增加一个移动的测试用例, 测试网址为 百度 移动鼠标到百度的设置,会出现下拉框
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import pytest
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
class TestActions:
def setup(self):
self.chrome_options = Options()
self.chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") # 指定配置好的 chrom
self.chrome_driver = r"./chromedriver.exe" # 驱动路径
self.driver = webdriver.Chrome(self.chrome_driver, chrome_options=self.chrome_options) # 加入驱动设置
# self.driver.get('https://sahitest.com/demo/clicks.htm') # 发起请求
# self.driver.maximize_window() # 设置为最大化
self.driver.implicitly_wait(3) # 添加一个隐式等待默认等待3秒
def teardown(self):
print('关闭浏览器')
time.sleep(1)
# self.driver.quit()
# 测试用例如果不加sleep的话,元素如果没加载出来,是会报错的,所以我们要加个隐式等待
@pytest.mark.skip # 不想执行这个测试用例可以加这个装饰器跳过
def test_clicks(self):
print('go')
dbl_click_me = self.driver.find_element_by_xpath("//input[@value='dbl click me']") # 双击
click_me = self.driver.find_element_by_xpath("//input[@value='click me']") # 单击
right_me = self.driver.find_element_by_xpath("// input[ @ value='right click me']") # 右键
action = ActionChains(self.driver) # 初始化
action.click(click_me) # 点击一次
action.double_click(dbl_click_me) # 双击两次
action.context_click(right_me) # 右键一次
action.perform() # 启动
def test_movie(self):
self.driver.get('https://www.baidu.com/') # 发起请求
move_mouse = self.driver.find_element_by_xpath("//span[@id='s-usersetting-top']") # 定位移动u元素
action = ActionChains(self.driver) # 初始化
action.move_to_element(move_mouse) # 移动光到设置去
action.perform() # 启动
if __name__ == '__main__':
pytest.main(['-vs', "test_action.py::TestActions"])
测试demo 2 网址为: https://sahitest.com/demo/dragDropMooTools.htm
代码大致同上, 增加一个跳过百度的装饰器,然后在下面新增一个方法 test_move2, 进行一个拖拽
def test_movie2(self):
self.driver.get('https://sahitest.com/demo/dragDropMooTools.htm') # 发起请求
drag_element = self.driver.find_element_by_xpath('//*[@id="dragger"]') # 拿起元素
drop_element1 = self.driver.find_element_by_xpath("/html/body/div[2]") # 放下元素
drop_element2 = self.driver.find_element_by_xpath('/html/body/div[3]') # 放下元素
drop_element3 = self.driver.find_element_by_xpath("/html/body/div[4]") # 放下元素
drop_element4 = self.driver.find_element_by_xpath("/html/body/div[5]") # 放下元素
action = ActionChains(self.driver) # 初始化
action.drag_and_drop(drag_element, drop_element1).drag_and_drop(drag_element, drop_element2).drag_and_drop(drag_element, drop_element3).drag_and_drop(drag_element,
drop_element4).perform() #链式写法perform
但是,如果这样写会出现一个情况

查了很多帖子,也不知道为什么会这样,有个模糊点的答案就是
因为ActionChains这个方法的动作添加是添加到一个list中,重复使用可能会出一些不可预知的问题
所以需要每次最好遇到行不懂的情况就重新写实例一个action, 改写如下
def test_movie2(self):
self.driver.get('https://sahitest.com/demo/dragDropMooTools.htm') # 发起请求
drag_element = self.driver.find_element_by_xpath('//*[@id="dragger"]') # 拿起元素
drop_element1 = self.driver.find_element_by_xpath("/html/body/div[2]") # 放下元素
drop_element2 = self.driver.find_element_by_xpath('/html/body/div[3]') # 放下元素
drop_element3 = self.driver.find_element_by_xpath("/html/body/div[4]") # 放下元素
drop_element4 = self.driver.find_element_by_xpath("/html/body/div[5]") # 放下元素
action = ActionChains(self.driver) # 初始化
action.drag_and_drop(drag_element, drop_element1).perform()
time.sleep(1)
action2 = ActionChains(self.driver) # 初始化
action2.drag_and_drop(drag_element, drop_element2).perform()
time.sleep(1)
action3 = ActionChains(self.driver) # 初始化
action3.drag_and_drop(drag_element, drop_element3).perform()
time.sleep(1)
action4 = ActionChains(self.driver) # 初始化
action4.drag_and_drop(drag_element, drop_element4).perform()

改三。。。发现是没有暂停时间的问题。。。以下代码也是可以的
def test_movie2(self):
self.driver.get('https://sahitest.com/demo/dragDropMooTools.htm') # 发起请求
drag_element = self.driver.find_element_by_xpath('//*[@id="dragger"]') # 拿起元素
drop_element1 = self.driver.find_element_by_xpath("/html/body/div[2]") # 放下元素
drop_element2 = self.driver.find_element_by_xpath('/html/body/div[3]') # 放下元素
drop_element3 = self.driver.find_element_by_xpath("/html/body/div[4]") # 放下元素
drop_element4 = self.driver.find_element_by_xpath("/html/body/div[5]") # 放下元素
action = ActionChains(self.driver) # 初始化
action.drag_and_drop(drag_element, drop_element1).pause(1).drag_and_drop(drag_element, drop_element2).pause(1).drag_and_drop(drag_element, drop_element3).pause(1).drag_and_drop(drag_element, drop_element4).pause(1).perform() # pause(1) 代表暂停1秒
用法 三
使用ActionChains模拟按键方法。用法如下
action = ActionChains(self.driver)
action.send_keys(Keys.BACK_SPACE)
# 或者action.key_down(Keys.CONTROL).send_keys('a').key_up(Keys.CONTROL)
action.perform()
测试网址: https://sahitest.com/demo/label.htm

测试效果,
1、在第一个 Username 中填入 lakes james,
2、 在第二个输入框使用全选,复制,粘贴到输入框
def test_movie3(self):
url = 'https://sahitest.com/demo/label.htm'
usernames = 'lakes'
passwds = 'james'
self.driver.get(url) # 发起请求
click_element = self.driver.find_element_by_xpath("//label[contains(text(),'Username')]//input[@type='textbox']") # 选中第一个框
second_element = self.driver.find_element_by_xpath("/html/body/label[2]/table/tbody/tr/td[2]/input")
action = ActionChains(self.driver)
action.click(click_element).pause(1).send_keys(usernames).pause(0.5).send_keys(Keys.SPACE).pause(1).send_keys(f'{passwds}').pause(1).send_keys( Keys.BACK_SPACE).pause(1).key_down(Keys.CONTROL).send_keys('a').pause(1).key_down(Keys.CONTROL).send_keys('c').pause(2).click(second_element).pause(1).key_down(Keys.CONTROL).send_keys('v').perform()
# 1、点击第一个元素然后等待1秒然后发送username和空格然后发送密码过去然后发送一个删除1个字母,然后全选然后点击复制,然后点击第二个元素,然后粘贴上去
# 2、ctrl + a 不能通过 action.send_keys(Keys.CONTROL, "a") 直接发送,需要 key_down之后再 send_keys再然后 key_up(Keys.CONTROL)

Keys 类键盘操作的常用方法:
Keys 类键盘操作的常用方法:
引入Keys类:
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)
...
#输入框输入内容
driver.find_element_by_id("kw1").send_keys("seleniumm")
time.sleep(3)
#删除多输入的一个m
driver.find_element_by_id("kw1").send_keys(Keys.BACK_SPACE)
time.sleep(3)
...
TouchAction用法
ActionChains和TouchAction可以用来模拟点击、双击、滑动等事件。ActionChains用于执行PC端的鼠标移动、按键、拖拽等事件;TouchActions用法与ActionChains类似,可以用来模拟PC和移动端的点击、滑动、拖拽等手势操作。,
ActionChains和TouchAction都是将动作存储在队列中,然后执行perform()方法,按队列顺序执行动作。
手势控制方法
double_tap 双击
flick 滑动
flick_element 从某个元素位置开始滑动
long_press 长按
move 手势移动指定偏移
Perform 执行
release 释放手势
scroll 点击并滚动
scroll_from_element 从某个元素位置开始手势点击并滚动(向下滑动为负数,向上滑动为正数)
flick_element——从某个元素位置开始手势滑动(负数:向上滑动,正数:向下滑动)
tap 在指定元素上点击
tap_and_hold 在指定元素上点击但不释放
例子: 打开百度搜索然后搜索湖人,下拉滑动到尽头
from selenium.webdriver import TouchActions
def test_serarch(self):
url = 'https://www.baidu.com/'
kw = '湖人'
self.driver.get(url) # 发起请求
input_element = self.driver.find_element_by_xpath("//input[@id='kw']") # 选中输入框
input_element.send_keys(kw) # 对选中的输入文字
search = self.driver.find_element_by_id("su") # 点击搜索
action = TouchActions(self.driver) # 初始化一个action
action.tap(search).perform() # 点击确认等待2秒之后执行, 并执行
action.scroll_from_element(input_element, 0, 10000).perform() # 传入三个元素。第一个元素是选定的起点,x,y 是滚动的偏移量

但是会报错,所以我们要对初始化的时候进行点修改
def setup(self):
self.chrome_options = Options()
self.chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") # 指定配置好的 chrom
self.chrome_options.add_experimental_option("w3c", False) # 设置为w3c
self.chrome_driver = r"./chromedriver.exe" # 驱动路径
self.driver = webdriver.Chrome(self.chrome_driver, chrome_options=self.chrome_options) # 加入驱动设置
# self.driver.get('https://sahitest.com/demo/clicks.htm') # 发起请求
# self.driver.maximize_window() # 设置为最大化
self.driver.implicitly_wait(3) # 添加一个隐式等待默认等待3秒
def teardown(self):
print('关闭浏览器')
# time.sleep(1)
selenium web控件的交互进阶的更多相关文章
- 2015.2.16 关于delphi web控件打开新网页时弹出关闭页面(js代码)出错的解决办法研究
参考网址1:http://www.csharpwin.com/csharpspace/2360.shtml...参考网址2:http://www.oschina.net/question/234345 ...
- 033. asp.netWeb用户控件之二将页面转换成web控件和使用Web控件显示热点新闻
访问Web用户控件的属性 ASP.NET提供的各种服务器控件都有其自身的属性和方法,程序开发人员可以灵活地使用服务器控件中的属性和方法开发程序.在用户控件中,程序开发人员也可以自行定义各种属性和方法, ...
- [MFC] MFC 打开HTML资源(用ID版,也可加载到自己的web控件上)
@ ^ @:如果是加载到web控件上,就把注释掉的解除注释(改为web控件点后面的函数),把下一句注释 BOOL Button::LoadFromResource(UINT nRes){//打开网页加 ...
- 译:c#生成条码的web控件
译文:http://www.codeproject.com/Tips/846860/Csharp-Barcode-Generator-Web-Control 在asp.net的web页用c#的web控 ...
- Javascript语法去控制Web控件的Enabled属性
Web控件当使用Enabled属性时,它生成html之后会变成了disabled了.我们为了能够在javascript去控制控件的禁用与启用,得从这个disabled入手.如:
- Web控件文本框Reset的功能
在前一篇中<怎样实现Web控件文本框Reset的功能>http://www.cnblogs.com/insus/p/4120889.html Insus.NET只实现了文本框的功能.单个或 ...
- 怎样实现Web控件文本框Reset的功能
在ASP.NET开发过程序,在数据插入之后,文本框TextBox控件需要Reset.如果只有一两个文件框也许没有什么问题,如果网页上有很多文本框,你就会有点问题了.再加上某一情形,一些文本框是有默认值 ...
- 基本的Web控件四
基本的Web控件用法二 ListBox控件 页面布局: <div> <h1>ListBox控件</h1> 学生列表: <br/> <asp:Lis ...
- 基本的Web控件三
基本的Web控件用法一 ListBox控件 页面布局: <div> <h1>ListBox控件</h1> 学生列表: <br/> <asp:Lis ...
- 基本的Web控件一
ASP.NET提供了与HTML元素相对应的基本Web控件,ASP.NET提供的基本的Web控件如下: 基本的Web控件 对应的HTML元素 Label ----------------- ...
随机推荐
- STM32使用DMA接收不定长数据
开启串口,是能串口全局中断 配置DMA并勾选Memory选项 继续配置工程并且生成代码 添加一些串口通讯使用的全局变量 #define BUFFER_SIZE 128 uint8_t Tx_Buf[5 ...
- 惰性载入(函数)-跟JS性能有关的思想
一.惰性载入概念: 惰性.懒惰.其实跟懒惰没有关系,就是图省事,把没意义的事少做.不做. 惰性载入函数:函数执行时会根据不同的判断分支最终选择合适的方案执行,但这样的分支判断仅会发生一次,后面的其他同 ...
- jquery的y一些实用方法
jquery的在线手册 jQuery获取Select选择的Text和Value:语法解释:1. $("#select_id").change(function(){//code.. ...
- 个人数据保全计划:(2) NAS基础知识
前言 距离去年国庆入手了NAS至今有好几个月时间了,NAS折腾起来有点麻烦,且实际作用因人而异,并没有想象中的好用,所以说好的这个系列一直没有更新~ 还有另一方面的原因,这些NAS的系统基于Linux ...
- Javaweb学习笔记第十六弹--Vue、Element
Vue(一套前端框架,MVVM主要用于实现数据的双向绑定) Vue快速入门 //新建HTML页面,引入Vue.js文件 <script src="js.Vue.js"> ...
- 多路复用IO:select poll epoll
[电话面试]io多路复用专题面试 这个真猛 有人做了笔记:点这里 select Select(Max+1,&rset,null,null,null)是因为0~max是max+1. 过程: 将文 ...
- P4774 倚天屠龙传 题解
其实这道题的主体并不难,主要是细节很多 我们可以把题目分成界限分明的两部分,第一部分,屠每条龙所用的剑只和当前拥有的剑有关.于是可以单独开一个数据结构按题目维护. 另一部分找到最小攻击次数,可以化作以 ...
- windows作业系统部署nfs服务
文件共享的需求是如何产生的? 据说当年美国和苏联冷战期间,双方都有摧毁对方的能力.而苏联 不怕死的性格让美国人多少有些害怕.美国当时害怕自己的军事指挥中心被苏联摧毁.于是,美国建立了阿帕网,并把自己的 ...
- ChannelInboundHandlerAdapter 与 SimpleChannelInboundHandler 功能详解
SimpleChannelInboundHandler [类的关系]:如下就是两个类的声明,SimpleChannelInboundHandler是继承 ChannelInboundHandlerAd ...
- OpenAI Kubernetes 相关博文读后笔记
一.概述 最近 ChatGPT 和其公司 OpenAI 特别火:ChatGPT 3, ChatGPT 3.5, New Bing, ChatGPT 4... 怀着学习的心态,这几天访问了 OpenAI ...