用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()
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.代码示例
- 点击操作
ActionChains(driver).click(click_btn).perform() # 单击按钮
ActionChains(driver).double_click(doubleclick_btn).perform() # 双击按钮
ActionChains(driver).context_click(rightclick_btn).perform() # 右键菜单
- 鼠标移动
action.move_to_element(more).perform() #移动到指定元素
action.move_by_offset(200, 100).perform() #从当前位置移动指定的距离
action.move_to_element_with_offset(more, 870, -4).perform() #从指定元素位置开始移动指定的距离
- 拖拽
'''定位元素的源位置'''
element_record = driver.find_elements_by_xpath("//td[text()='日志']")[1]
element_knowledge = driver.find_element_by_xpath("//td[text()='知识']")
element_opp = driver.find_elements_by_xpath("//td[text()='商机']")[1]
element_pro = driver.find_elements_by_xpath("//td[text()='产品']")[1]
'''定位元素要移动到的目标位置'''
target= driver.find_element_by_xpath("//td[text()='此位置未添加菜单']")
'''将日志元素拖拽到目标位置'''
ActionChains(driver).click_and_hold(element_record).perform() # 在日志元素上点击鼠标左键,不松开
ActionChains(driver).move_by_offset(2, 20).perform() # 鼠标相对于当前位置移动一定距离
ActionChains(driver).move_by_offset(2, 20).perform() # 鼠标相对于当前位置移动一定距离
ActionChains(driver).move_to_element(target).perform() # 鼠标移动到目标位置
ActionChains(driver).release(element_record).perform() # 释放鼠标左键
# ActionChains(driver).drag_and_drop(element_record,target).perform()# 与上面5步操作结果相同
'''2.将知识元素拖拽到目标位置'''
ActionChains(driver).click_and_hold(element_knowledge).release(target).perform()
'''3.将商机元素拖拽到目标位置'''
ActionChains(driver).click_and_hold(element_opp).move_to_element(target).release().perform()
'''4.将产品元素拖拽到目标位置'''
# action.drag_and_drop_by_offset(element_pro, -600, 30).perform()
ActionChains(driver).click_and_hold(element_pro).move_by_offset(-600, 30).release().perform()
- 按键
模拟按键有多种方法,能用win32api来实现,能用SendKeys来实现,也可以用selenium的WebElement对象的send_keys()方法来实现,这里ActionChains类也提供了几个模拟按键的方法。
action.key_down(Keys.COMMAND).send_keys('a').key_up(Keys.COMMAND).perform() # ctrl+a 全选
action.key_down(Keys.COMMAND).send_keys('c').key_up(Keys.COMMAND).perform() # ctrl+c 复制
action.key_down(Keys.COMMAND).send_keys('v').key_up(Keys.COMMAND).perform() # ctrl+v
常用按键
- Keys.BACK_SPACE #删除键–Backspace
- Keys.SPACE #空格键 Space
- Keys.TAB #制表键 Tab
- Keys.ESCAPE #回退键 ESC
- Keys.ENTER #回车键 Enter
- Keys.F5 #键盘F5(可模拟F1-F12)
- Keys.CONTROL #Ctrl键
- Keys.SHIFT #shift键
- Keys.DELETE #delete键