玩转python selenium鼠标键盘操作(ActionChains)


Posted in Python onApril 12, 2020

用selenium做自动化,有时候会遇到需要模拟鼠标操作才能进行的情况,比如单击、双击、点击鼠标右键、拖拽等等。而selenium给我们提供了一个类来处理这类事件——ActionChains

selenium.webdriver.common.action_chains.ActionChains(driver)

这个类基本能够满足我们所有对鼠标操作的需求。

1.ActionChains基本用法

首先需要了解ActionChains的执行原理,当你调用ActionChains的方法时,不会立即执行,而是会将所有的操作按顺序存放在一个队列里,当你调用perform()方法时,队列中的时间会依次执行。

这种情况下我们可以有两种调用方法: 

•链式写法

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()

 •分步写法

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)
actions.perform()

 两种写法本质是一样的,ActionChains都会按照顺序执行所有的操作。

2.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) ——发送某个键到指定元素

接下来用示例来详细说明和演示每一个方法的用法:

3.代码示例

1. 点击操作

示例网址http://sahitest.com/demo/clicks.htm

代码:

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep


driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.maximize_window()
driver.get('http://sahitest.com/demo/clicks.htm')

click_btn = driver.find_element_by_xpath('//input[@value="click me"]') # 单击按钮
doubleclick_btn = driver.find_element_by_xpath('//input[@value="dbl click me"]') # 双击按钮
rightclick_btn = driver.find_element_by_xpath('//input[@value="right click me"]') # 右键单击按钮


ActionChains(driver).click(click_btn).double_click(doubleclick_btn).context_click(rightclick_btn).perform() # 链式用法

print driver.find_element_by_name('t2').get_attribute('value')

sleep(2)
driver.quit()

结果:

[CLICK][DOUBLE_CLICK][RIGHT_CLICK]

2.鼠标移动

示例网址http://sahitest.com/demo/mouseover.htm

示例代码:

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep

driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.maximize_window()
driver.get('http://sahitest.com/demo/mouseover.htm')

write = driver.find_element_by_xpath('//input[@value="Write on hover"]') # 鼠标移动到此元素,在下面的input框中会显示“Mouse moved”
blank = driver.find_element_by_xpath('//input[@value="Blank on hover"]') # 鼠标移动到此元素,会清空下面input框中的内容

result = driver.find_element_by_name('t1')

action = ActionChains(driver)
action.move_to_element(write).perform() # 移动到write,显示“Mouse moved”
print result.get_attribute('value')

# action.move_to_element(blank).perform()
action.move_by_offset(10, 50).perform() # 移动到距离当前位置(10,50)的点,与上句效果相同,移动到blank上,清空
print result.get_attribute('value')

action.move_to_element_with_offset(blank, 10, -40).perform() # 移动到距离blank元素(10,-40)的点,可移动到write上
print result.get_attribute('value')

sleep(2)
driver.quit()

结果

Mouse moved

Mouse moved

3.拖拽

示例网址http://sahitest.com/demo/dragDropMooTools.htm

代码:

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep

driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.maximize_window()
driver.get('http://sahitest.com/demo/dragDropMooTools.htm')

dragger = driver.find_element_by_id('dragger') # 被拖拽元素
item1 = driver.find_element_by_xpath('//div[text()="Item 1"]') # 目标元素1
item2 = driver.find_element_by_xpath('//div[text()="Item 2"]') # 目标2
item3 = driver.find_element_by_xpath('//div[text()="Item 3"]') # 目标3
item4 = driver.find_element_by_xpath('//div[text()="Item 4"]') # 目标4

action = ActionChains(driver)
action.drag_and_drop(dragger, item1).perform() # 1.移动dragger到目标1
sleep(2)
action.click_and_hold(dragger).release(item2).perform() # 2.效果与上句相同,也能起到移动效果
sleep(2)
action.click_and_hold(dragger).move_to_element(item3).release().perform() # 3.效果与上两句相同,也能起到移动的效果
sleep(2)
# action.drag_and_drop_by_offset(dragger, 400, 150).perform() # 4.移动到指定坐标
action.click_and_hold(dragger).move_by_offset(400, 150).release().perform() # 5.与上一句相同,移动到指定坐标
sleep(2)
driver.quit()

结果:

dropped dropped dropped dropped

一般用坐标定位很少,用上例中的方法1足够了,如果看源码,会发现方法2其实就是方法1中的drag_and_drop()的实现。注意:拖拽使用时注意加等待时间,有时会因为速度太快而失败。

4.按键

模拟按键有多种方法,能用win32api来实现,能用SendKeys来实现,也可以用selenium的WebElement对象的send_keys()方法来实现,这里ActionChains类也提供了几个模拟按键的方法。

示例网址http://sahitest.com/demo/keypress.htm

代码1:

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep

driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.maximize_window()
driver.get('http://sahitest.com/demo/keypress.htm')

key_up_radio = driver.find_element_by_id('r1') # 监测按键升起
key_down_radio = driver.find_element_by_id('r2') # 监测按键按下
key_press_radio = driver.find_element_by_id('r3') # 监测按键按下升起

enter = driver.find_elements_by_xpath('//form[@name="f1"]/input')[1] # 输入框
result = driver.find_elements_by_xpath('//form[@name="f1"]/input')[0] # 监测结果

# 监测key_down
key_down_radio.click()
ActionChains(driver).key_down(Keys.CONTROL, enter).key_up(Keys.CONTROL).perform()
print result.get_attribute('value')

# 监测key_up
key_up_radio.click()
enter.click()
ActionChains(driver).key_down(Keys.SHIFT).key_up(Keys.SHIFT).perform()
print result.get_attribute('value')

# 监测key_press
key_press_radio.click()
enter.click()
ActionChains(driver).send_keys('a').perform()
print result.get_attribute('value')
driver.quit()

结果:

key downed charCode=[0] keyCode=[17] CTRL
key upped charCode=[0] keyCode=[16] NONE
key pressed charCode=[97] keyCode=[0] NONE

示例2:

示例网址http://sahitest.com/demo/label.htm

代码:

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from time import sleep

driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.maximize_window()

driver.get('http://sahitest.com/demo/label.htm')

input1 = driver.find_elements_by_tag_name('input')[3]
input2 = driver.find_elements_by_tag_name('input')[4]

action = ActionChains(driver)
input1.click()
action.send_keys('Test Keys').perform()
action.key_down(Keys.CONTROL).send_keys('a').key_up(Keys.CONTROL).perform() # ctrl+a
action.key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform() # ctrl+c

action.key_down(Keys.CONTROL, input2).send_keys('v').key_up(Keys.CONTROL).perform() # ctrl+v

print input1.get_attribute('value')
print input2.get_attribute('value')

driver.quit()

结果:

Test Keys
Test Keys

复制粘贴用WebElement< input >.send_keys()也能实现,大家可以试一下,也可以用更底层的方法,同时也是os弹框的处理办法之一的win32api,有兴趣也可以试试SendKeys、keybd_event

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python入门篇之数字
Oct 20 Python
python编写的最短路径算法
Mar 25 Python
Python 3.x基于Xml数据的Http请求方法
Dec 28 Python
pyqt 实现为长内容添加滑轮 scrollArea
Jun 19 Python
简单分析python的类变量、实例变量
Aug 23 Python
Python变量、数据类型、数据类型转换相关函数用法实例详解
Jan 09 Python
win10下opencv-python特定版本手动安装与pip自动安装教程
Mar 05 Python
使用Python matplotlib作图时,设置横纵坐标轴数值以百分比(%)显示
May 16 Python
Python 如何查找特定类型文件
Aug 17 Python
python matlab库简单用法讲解
Dec 31 Python
pytorch中index_select()的用法详解
Jan 06 Python
深入理解Python变量的数据类型和存储
Feb 01 Python
Python selenium文件上传方法汇总
Nov 19 #Python
Python selenium如何设置等待时间
Sep 15 #Python
Python selenium 父子、兄弟、相邻节点定位方式详解
Sep 15 #Python
Python selenium 三种等待方式详解(必会)
Sep 15 #Python
python使用pymysql实现操作mysql
Sep 13 #Python
python实现可以断点续传和并发的ftp程序
Sep 13 #Python
Python安装第三方库及常见问题处理方法汇总
Sep 13 #Python
You might like
thinkphp3.0 模板中函数的使用
2012/11/13 PHP
一个PHP实现的轻量级简单爬虫
2015/07/08 PHP
window.location和document.location的区别分析
2008/12/23 Javascript
Javascript 键盘keyCode键码值表
2009/12/24 Javascript
IE6下通过a标签点击切换图片的问题
2010/11/14 Javascript
jquery实现手风琴效果实例代码
2013/11/15 Javascript
JavaScript的jQuery库中function的存在和参数问题
2015/08/13 Javascript
纯css实现窗户玻璃雨滴逼真效果
2015/08/23 Javascript
Node.js项目中调用JavaScript的EJS模板库的方法
2016/03/11 Javascript
jQuery事件用法详解
2016/10/06 Javascript
JS给Array添加是否包含字符串的简单方法
2016/10/29 Javascript
jQuery插件HighCharts绘制2D柱状图、折线图和饼图的组合图效果示例【附demo源码下载】
2017/03/09 Javascript
页面间固定参数,通过cookie传值的实现方法
2017/05/31 Javascript
Node.js应用设置安全的沙箱环境
2018/04/23 Javascript
详解Vue.js在页面加载时执行某个方法
2018/11/20 Javascript
在Create React App中使用CSS Modules的方法示例
2019/01/15 Javascript
vue 父组件中调用子组件函数的方法
2019/06/06 Javascript
Node如何后台数据库使用增删改查功能
2019/11/21 Javascript
JavaScript实现多球运动效果
2020/09/07 Javascript
Python基于Tkinter的HelloWorld入门实例
2015/06/17 Python
深入解析Python中的lambda表达式的用法
2015/08/28 Python
浅谈numpy库的常用基本操作方法
2018/01/09 Python
python+ffmpeg批量去视频开头的方法
2019/01/09 Python
Python docx库用法示例分析
2019/02/16 Python
python安装requests库的实例代码
2019/06/25 Python
python实现扫雷游戏
2020/03/03 Python
VSCode基础使用与VSCode调试python程序入门的图文教程
2020/03/30 Python
Python JSON常用编解码方法代码实例
2020/09/05 Python
Python为何不支持switch语句原理详解
2020/10/21 Python
Under Armour安德玛法国官网:美国高端运动科技品牌
2018/06/29 全球购物
澳大利亚儿童精品仓库:Goo & Co.
2019/06/20 全球购物
蔻驰英国官网:COACH英国
2020/07/19 全球购物
计算机专业优秀大学生自我总结
2014/01/21 职场文书
国旗下讲话演讲稿
2014/05/08 职场文书
县政府班子个人对照检查材料
2014/10/05 职场文书
试用期工作表现自我评价
2015/03/06 职场文书