演练环境:https://vip.ceshiren.com/#/ui_study/action_chains
一、使用场景
使用场景 | 对应事件 |
---|---|
复制粘贴 | 键盘事件 |
拖动元素到某个位置 | 鼠标事件 |
鼠标悬停 | 鼠标事件 |
滚动到某个元素 | 滚动事件 |
使用触控笔点击 | 触控笔事件(了解即可) |
二、ActionChains类
Selenium的ActionChains类是用于执行一系列的鼠标和键盘操作。它提供了模拟用户行为的方法,例如拖拽、悬停、点击、按下和释放等。
1、构造方法
def __init__(self, driver: WebDriver, duration: int = 250, devices: list[AnyDevice] | None = None) -> None:
"""Creates a new ActionChains.
:Args:
- driver: The WebDriver instance which performs user actions.
- duration: override the default 250 msecs of DEFAULT_MOVE_DURATION in PointerInput
"""
self._driver = driver
mouse = None
keyboard = None
wheel = None
if devices is not None and isinstance(devices, list):
for device in devices:
if isinstance(device, PointerInput):
mouse = device
if isinstance(device, KeyInput):
keyboard = device
if isinstance(device, WheelInput):
wheel = device
self.w3c_actions = ActionBuilder(driver, mouse=mouse, keyboard=keyboard, wheel=wheel, duration=duration)
- 说明:只有driver参数是必传的,创建一个动作对象;
2、使用步骤
- 1、实例化ActionChains得到动作对象;
- 2、动作对象调用方法实现键盘和鼠标事件;
- 3、调用
perform()
方法执行动作;
3、动作方法
(1)鼠标点击
-
click:点击元素-左键单击;
-
click_and_hold:鼠标左键按住某个元素,长按;
-
release:在元素上释放按住的鼠标按钮。
-
context_click:右键单击;
-
double_click:双击;
(2)鼠标拖拽
-
drag_and_drop:按住源元素上的鼠标左键,然后移动到目标元素并松开鼠标按钮—拖动某个元素到某个元素;
-
drag_and_drop_by_offset:按住源元素上的鼠标左键,然后移动到目标偏移量并松开鼠标按钮—拖动某个元素到某个位置;
(3)鼠标移动-悬停
-
move_by_offset:移动鼠标到指定位置。
-
move_to_element:异动鼠标到指定元素。
-
move_to_element_with_offset:将鼠标移动到指定元素的偏移量位置,偏移量相对于元素的视图中心点。
(4)页面滚动
-
scroll_to_element:滚动到某个元素,意思是让元素可见;
-
scroll_by_amount:滚动到某个坐标,坐标原点在左上角;
-
scroll_from_origin:根据提供的滚动量和滚动基准进行滚动。滚动基准可以是元素的中心或视口的左上角加上任何偏移量。如果基准是元素,并且元素不在视口中,则首先将元素底部滚动到视口底部。
(5)模拟键盘
-
key_down(key, element=None):用于模拟按下键盘上的键并保持按下状态。该方法可以在进行一些复杂的键盘操作时使用。
-
key
: 要按下的键值,可以是键盘上的任何一个键,如keys.SHIFT
、keys.ENTER
等。详细的键值可以参考Selenium的Keys类。 - 该方法常用于需要模拟快捷键、组合键等键盘操作的场景。需要注意的是,
key_down
方法只是模拟按下键盘上的键,并不会自动释放,如果需要释放按键的状态,可以使用key_up
方法或release
方法。 - key_down只是按下,其并不能实现esc、tab、enter、↑这些按键输入,这些输入需要使用send_keys;
-
-
key_up:释放key_down方法模拟按下键盘上的键;
-
send_keys:给当前聚焦的元素发送键盘按键输入;
-
该方法常用于模拟用户在输入框、文本域等地方输入文本、快捷键等操作。可以使用键盘上的字符、特殊键或组合键等作为输入。
-
需要注意的是,
send_keys
方法会将文本发送到当前激活或焦点所在的元素上,如果需要在特定的元素上进行键盘输入,可以使用click
方法或move_to_element
方法先将焦点切换到对应元素。
-
-
send_keys_to_element:给指定元素发送键盘输入;
(6)其他方法
-
reset_actions:清除已存储在本地和远程端的操作;
-
pause:在指定的持续时间内暂停所有输入(以秒为单位)。
三、相关场景和案例
1、模拟键盘按键
- 需求:在页面输入框输入大写字母,并控制键盘按键实现输入框内容响应
- 地址:
https://vip.ceshiren.com/#/ui_study/keypress
代码实现:
"""
模拟键盘按键
"""
import time
from selenium import webdriver
from selenium.webdriver import ActionChains, Keys
from selenium.webdriver.common.by import By
driver = webdriver.Edge()
driver.maximize_window()
driver.get("https://vip.ceshiren.com/#/ui_study/keypress")
driver.implicitly_wait(5)
# 创建操作对象-
action = ActionChains(driver)
# 定位元素-按回车enter触发事件
enterEl = driver.find_element(By.XPATH,'//*[@id="press_enter"]/div/input')
# 按下shift键输入内容
action.key_down(Keys.SHIFT,enterEl).send_keys("enter")
#模拟键盘enter键
action.send_keys(Keys.ENTER)
# 执行动作
action.perform()
time.sleep(2)
# 定位元素-按删除delete触发事件
deleteEl = driver.find_element(By.XPATH,'//*[@id="press_delete"]/div/input')
# 链式调用-按下shift-输入
# 因为上面已经把shift按下了,所以这里不需要再按shift
# action.key_down(Keys.SHIFT,deleteEl).send_keys("delete")
deleteEl.send_keys("delete")
# 按下delete
action.send_keys(Keys.DELETE).perform()
time.sleep(2)
# 定位元素-按退出esc触发事件
escEl = driver.find_element(By.XPATH,'//*[@id="press_esc"]/div/input')
# 链式调用-按下shift-输入---很有意思,到这里的时候shift又没有被按下了,所以要重新按下shift,不信你换注释了的赋值试试
# escEl.send_keys("esccccc")
action.key_down(Keys.SHIFT,escEl).send_keys("esc")
# 按下esc
action.send_keys(Keys.ESCAPE).perform()
time.sleep(2)
# 定位元素-按空格tab触发事件
tabEl = driver.find_element(By.XPATH,'//*[@id="press_tab"]/div/input')
tabEl.send_keys("按空格tab触发事件")
# 模拟键盘delete键并执行
action.send_keys(Keys.TAB).perform()
time.sleep(2)
# 定位元素-按上up触发事件
upEl = driver.find_element(By.XPATH,'//*[@id="press_up"]/div/input')
upEl.send_keys("按上up触发事件")
# 模拟键盘delete键并执行
action.send_keys(Keys.UP).perform()
time.sleep(2)
# 定位元素-按左left触发事件
downEl = driver.find_element(By.XPATH,'//*[@id="press_left"]/div/input')
downEl.send_keys("按左left触发事件")
# 模拟键盘delete键并执行
action.send_keys(Keys.LEFT).perform()
time.sleep(5)
driver.quit()
2、鼠标移动、双击、右击
- 地址:
https://vip.ceshiren.com/#/ui_study/mouseover
代码实现:
"""
鼠标:双击、右击、鼠标移动
"""
import time
from selenium import webdriver
from selenium.webdriver import ActionChains, Keys
from selenium.webdriver.common.by import By
driver = webdriver.Edge()
driver.maximize_window()
driver.get("https://vip.ceshiren.com/#/ui_study/mouseover")
driver.implicitly_wait(5)
# 创建操作对象-
action = ActionChains(driver)
# 鼠标移动到-鼠标移入
# 定位鼠标移入元素
mouseIn = driver.find_element(By.XPATH,'//*[@class="el-button el-button--primary"]/span[(text()="鼠标移入")]')
action.move_to_element(mouseIn).perform()
time.sleep(2)
# 鼠标移动到-点击两次响应
# 定位点击两次响应元素
doubleBtn = driver.find_element(By.XPATH,'//*[@class="el-button el-button--primary"]/span[(text()="点击两次响应")]')
# 鼠标移过去并双击
# 双击的时候,如果鼠标在元素位置可以直接双击,不用传元素对象过去
# 如果鼠标不在元素位置,就需要传元素对象过去
action.move_to_element(doubleBtn).double_click().perform()
time.sleep(2)
# 鼠标右击
action.context_click().perform()
time.sleep(2)
driver.quit()
3、鼠标拖拽元素-拖拽图片验证码
地址:https://vip.ceshiren.com/#/ui_study/action_chains
代码实现:
"""
鼠标拖拽
"""
import time
from selenium import webdriver
from selenium.webdriver import ActionChains, Keys
from selenium.webdriver.common.by import By
driver = webdriver.Edge()
driver.maximize_window()
driver.get("https://vip.ceshiren.com/#/ui_study/action_chains")
driver.implicitly_wait(5)
# 创建操作对象-
action = ActionChains(driver)
# 定位源元素
originEl = driver.find_element(By.XPATH,'//*[@class="item1"]')
# 定位目标元素
targetEl = driver.find_element(By.XPATH,'//*[@class="item3"]')
# 拖拽
action.drag_and_drop(originEl,targetEl).perform()
time.sleep(2)
driver.quit()
4、鼠标移动并悬浮–下拉框处理
地址:https://vip.ceshiren.com/#/ui_study/action_chains2
代码实现:
"""
鼠标移动悬浮-下拉框处理
"""
import time
from selenium import webdriver
from selenium.webdriver import ActionChains, Keys
from selenium.webdriver.common.by import By
driver = webdriver.Edge()
driver.maximize_window()
driver.get("https://vip.ceshiren.com/#/ui_study/action_chains2")
driver.implicitly_wait(5)
# 创建操作对象-
action = ActionChains(driver)
# 定位下拉框元素
selectEl = driver.find_element(By.XPATH,'//*[@class="title"]')
# 鼠标移动过去
action.move_to_element(selectEl).perform()
time.sleep(2)
# 定位下拉框内的元素
jybEl = driver.find_element(By.XPATH,'//*[(text()=" 就业班 ")]')
# 移动上去
action.move_to_element(jybEl).perform()
time.sleep(2)
# 定位下拉框内的元素
jybEl = driver.find_element(By.XPATH,'//*[(text()=" 定向班 ")]')
# 移动上去
action.move_to_element(jybEl).perform()
time.sleep(2)
# 定位下拉框内的元素
jybEl = driver.find_element(By.XPATH,'//*[(text()=" 测开班 ")]')
# 移动上去
action.move_to_element(jybEl).perform()
time.sleep(2)
# 定位下拉框内的元素
jybEl = driver.find_element(By.XPATH,'//*[(text()=" 管理班 ")]')
# 移动上去
action.move_to_element(jybEl).perform()
time.sleep(2)
# 定位下拉框内的元素
jybEl = driver.find_element(By.XPATH,'//*[(text()=" 性能班 ")]')
# 移动上去
action.move_to_element(jybEl).perform()
# 模拟鼠标点击最后一个--鼠标就在当前位置,click不用传元素对象
action.click().perform()
time.sleep(2)
# 再点击单选框
jyBox = driver.find_element(By.XPATH,"//*[@name='jy']")
action.move_to_element(jyBox).click().perform()
time.sleep(5)
driver.quit()
5、页面滚动–炸了–TODO
- 注意:页面滚动的方法需要在selenium4.2及以上版本才会生效;
# 升级selenium
pip install -U selenium==4.15.1
"""
页面滚动
"""
import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
driver = webdriver.Edge()
driver.maximize_window()
driver.get("https://ceshiren.com")
driver.implicitly_wait(15)
# 创建操作对象-
action = ActionChains(driver)
#试一下能不能定位到
a = driver.find_element(By.XPATH,'//*[(text()="使用代理服务器录制请求")]')
action.scroll_to_element(a).perform()
time.sleep(5)