Selenium4 文件上传和下载
Selenium 鼠标与键盘操作全攻略(2025 最新版)
鼠标 + 键盘 = 真实用户行为的灵魂
掌握ActionChains与Keys,让自动化像真人一样操作!
一、核心工具概览
| 工具 | 用途 | 所属模块 |
|---|---|---|
ActionChains | 鼠标操作(悬停、拖拽、右键等) | selenium.webdriver.common.action_chains |
Keys | 键盘ure 键盘操作(回车、Ctrl+A、组合键) | selenium.webdriver.common.keys |
二、ActionChains —— 鼠标操作王者
1. 初始化
from selenium.webdriver.common.action_chains import ActionChains
actions = ActionChains(driver)
2. 常用鼠标操作(必背 8 个)
| 操作 | 方法 | 示例 |
|---|---|---|
| 移动到元素 | move_to_element(elem) | 悬停菜单 |
| 点击 | click(elem) | 左键点击 |
| 双击 | double_click(elem) | 打开详情 |
| 右键 | context_click(elem) | 右键菜单 |
| 拖拽 | drag_and_drop(source, target) | 拖动滑块 |
| 按住不放 | click_and_hold(elem) | 拖拽开始 |
| 释放 | release() | 拖拽结束 |
| 暂停 | pause(seconds) | 模拟真人延迟 |
# 链式写法(推荐!)
actions.move_to_element(menu) \
.pause(0.5) \
.click(sub_item) \
.perform()
.perform()必须调用! 否则动作不执行
三、Keys —— 键盘操作全家桶
from selenium.webdriver.common.keys import Keys
常用按键(必背 15 个)
| 键 | 代码 | 说明 |
|---|---|---|
| 回车 | Keys.ENTER | 提交表单 |
| Tab | Keys.TAB | 切换输入框 |
| Esc | Keys.ESCAPE | 关闭弹窗 |
| 空格 | Keys.SPACE | 滚动/复选 |
| 退格 | Keys.BACKSPACE | 删除字符 |
| 删除 | Keys.DELETE | 删除选中 |
| 全选 | Keys.CONTROL + "a" | Ctrl+A |
| 复制 | Keys.CONTROL + "c" | Ctrl+C |
| 粘贴 | Keys.CONTROL + "v" | Ctrl+V |
| 剪切 | Keys.CONTROL + "x" | Ctrl+X |
| 上/下/左/右 | Keys.ARROW_UP 等 | 方向键 |
| Page Up/Down | Keys.PAGE_UP | 翻页 |
| Home/End | Keys.HOME | 跳到开头/结尾 |
| F1~F12 | Keys.F1 | 功能键 |
input_box.send_keys("Selenium")
input_box.send_keys(Keys.CONTROL, "a") # 全选
input_box.send_keys(Keys.CONTROL, "c") # 复制
input_box.send_keys(Keys.DELETE) # 清空
四、鼠标 + 键盘组合技(实战)
1. 悬停菜单 → 点击子项
menu = driver.find_element(By.ID, "nav")
submenu = driver.find_element(By.LINK_TEXT, "设置")
ActionChains(driver) \
.move_to_element(menu) \
.pause(1) \
.click(submenu) \
.perform()
2. 拖拽滑块验证
slider = driver.find_element(By.ID, "slider")
target = driver.find_element(By.ID, "target")
ActionChains(driver) \
.click_and_hold(slider) \
.move_by_offset(300, 0) \
.release() \
.perform()
3. 输入框:全选 + 替换内容
elem = driver.find_element(By.ID, "search")
elem.send_keys("旧内容")
elem.send_keys(Keys.CONTROL, "a") # 全选
elem.send_keys("新内容") # 替换
4. 右键 → 选择“另存为”
img = driver.find_element(By.CSS_SELECTOR, "img.logo")
ActionChains(driver) \
.context_click(img) \
.pause(1) \
.send_keys(Keys.ARROW_DOWN) \
.send_keys(Keys.ARROW_DOWN) \
.send_keys(Keys.ENTER) \
.perform()
五、进阶技巧
1. 坐标拖拽(精准控制)
# 从 (x1,y1) 拖到 (x2,y2)
ActionChains(driver) \
.move_by_offset(x1, y1) \
.click_and_hold() \
.move_by_offset(x2-x1, y2-y1) \
.release() \
.perform()
2. 滚动页面(JS 更快)
# ActionChains 滚动(不推荐,慢)
actions.send_keys(Keys.PAGE_DOWN).perform()
# 推荐:JS 滚动
driver.execute_script("window.scrollBy(0, 1000);")
3. 模拟真人打字(防检测)
import random
import time
def human_type(element, text):
for char in text:
element.send_keys(char)
time.sleep(random.uniform(0.05, 0.2)) # 随机延迟
human_type(input_box, "hello world")
六、完整实战:电商加入购物车(鼠标 + 键盘)
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
wait = WebDriverWait(driver, 10)
actions = ActionChains(driver)
try:
driver.get("https://httpbin.org/forms/post")
driver.maximize_window()
# 1. 悬停“尺寸”区域
size_area = wait.until(EC.presence_of_element_located((By.XPATH, "//b[text()='Size:']/..")))
actions.move_to_element(size_area).perform()
# 2. 选择“小号”(点击)
small_radio = driver.find_element(By.XPATH, "//input[@value='small']")
actions.click(small_radio).perform()
# 3. 多选配料(键盘辅助)
cheese = driver.find_element(By.XPATH, "//input[@value='cheese']")
bacon = driver.find_element(By.XPATH, "//input[@value='bacon']")
actions.click(cheese).send_keys(Keys.SPACE).click(bacon).perform()
# 4. 输入备注 + 提交
comments = driver.find_element(By.NAME, "comments")
comments.send_keys("不要辣")
comments.send_keys(Keys.TAB) # 跳到提交按钮
actions.send_keys(Keys.ENTER).perform()
print("订单提交成功!")
finally:
driver.quit()
七、常见问题 & 解决方案
| 问题 | 原因 | 解决 |
|---|---|---|
MoveTargetOutOfBoundsException | 坐标超出窗口 | 先 scrollIntoView |
ElementNotInteractable | 元素被遮挡 | 用 JS 点击 |
| 拖拽失败 | 目标未就绪 | 加 WebDriverWait |
| 键盘事件无效 | 焦点不在输入框 | 先 click() |
# 强制聚焦
driver.execute_script("arguments[0].focus();", element)
八、最佳实践总结
| 原则 | 推荐 |
|---|---|
| 链式写法 | 一条 ActionChains 完成多步 |
| 等待 | 操作前用 WebDriverWait |
| JS 兜底 | 复杂交互失败时用 execute_script |
| 防检测 | 加 pause() + 随机延迟 |
| 封装 | 写成函数复用 |
def hover_and_click(driver, hover_elem, click_elem):
ActionChains(driver) \
.move_to_element(hover_elem) \
.pause(0.5) \
.click(click_elem) \
.perform()
九、推荐工具
| 工具 | 用途 |
|---|---|
| SelectorsHub | 快速定位 |
| Event Listener | 查看 JS 事件 |
| Puppeteer | 更强鼠标控制(参考) |
十、一句话总结
ActionChains + Keys = 鼠标键盘自由控制,真实用户行为 100% 还原
下一步:
想看 10 个高难度交互案例(滑块验证、画布签名、富文本编辑器)?
回复 mouse_pro 我发你一个 防检测级交互框架!
终极模板(复制即用):
def safe_action(driver):
return ActionChains(driver).pause(0.3) # 每步加 0.3s 延迟
# 使用
safe_action(driver) \
.move_to_element(menu) \
.click(item) \
.perform()
def type_like_human(elem, text):
for c in text:
elem.send_keys(c)
time.sleep(random.uniform(0.1, 0.3))
现在,你的脚本不再是“机器人”,而是“真人”!