鼠标操作演示 · ActionChains

鼠标 8 大操作全解析:左击 · 右击 · 双击 · 移动(5种) · 按住 · 拖拽(5种) · 释放 · 滚动(3种)

使用说明

本页面是 Selenium ActionChains 鼠标操作的交互式演示区,按 8 种鼠标操作分为 8 个独立区域:
① 左击 click —— 最基础的单击操作,计数器演示
② 右击 context_click —— 触发右键菜单
③ 双击 double_click —— 双击切换开关状态
④ 移动 move_to_element等 —— 光标定位到元素中心 / 元素内偏移点 / 视口坐标;地图坐标演示 + 小球分步移动
⑤ 按住不松 click_and_hold —— 按下不释放,进度条持续增长
⑥ 拖拽 drag_and_drop等 —— 一步式 A→B 快速拖 + A→B 带偏移精确落位
⑦ 释放 release —— 分步式:按住→移动→释放,对比 release 的作用 + 贝塞尔曲线模拟真实轨迹
⑧ 滚动 scroll_by_amount 等 —— 原生 3 种方法 + 旧版 JS 注入兜底
每个区域提供对应的 API 说明 + 可点击的交互式 demo + Python Selenium 代码(一键复制)。

左击 右击 双击 移动 按住 释放 拖拽 滚动
01 · 左击

左击 click(最基础的鼠标操作)

ActionChains(driver).click(el).perform()
click() 的两种写法:
① element.click() —— 最简单,直接在元素上调用
② ActionChains(driver).click(element).perform() —— 适合和 hover / 拖拽 / 按键等其他动作链式组合; click(el) 会自动先 move_to_element(el),换成无参 click() 则点"当前鼠标位置"(初始坐标 (0, 0),即视口左上角),需要前面先链 move_to_element / move_to_element_with_offset 等把鼠标送到位
左击演示:点击下面按钮,数字 +1
0
点击次数
操作说明:
• 鼠标左键单击 计数器按钮
• 观察数字变化 & 按钮反馈(缩放动画)
• 对应 Selenium API:el.click() 或 ActionChains(driver).click(el).perform()
[状态] 等待左击操作...
Python Selenium · 左击 click
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains

# 1. 启动浏览器 + 打开演示页面
driver = webdriver.Chrome()
driver.get("https://autotest-505.pages.dev/mouse_op_tech.html")

# 2. 定位元素
counter = driver.find_element(By.ID, "clickCounter")

# 方式①:直接 click(最常用)
counter.click()

# 方式②:ActionChains.click(可链式组合)
# click(el) 内部会先自动 move_to_element(el),再无参 click() 点当前位置
actions = ActionChains(driver)
actions.click(counter).perform()

# 方式②的等价写法:显式链 move_to_element + 无参 click()
actions.move_to_element(counter).click().perform()

# 3. 操作完成后关闭浏览器
driver.quit()
02 · 右击

右击 context_click(触发右键菜单)

ActionChains(driver).context_click(el).perform()
右键场景:文件管理器、代码编辑器、桌面图标 —— 很多右键菜单是网页的 重要功能入口。 Selenium 中不能用 element.click() 触发右键,必须用 ActionChains.context_click()。
右击演示:在粉色区域点右键,弹出菜单
在此区域点击鼠标右键
或用 ActionChains.context_click
[状态] 等待右键操作...
Python Selenium · 右击 context_click
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
import time

# 1. 启动浏览器 + 打开演示页面
driver = webdriver.Chrome()
driver.get("https://autotest-505.pages.dev/mouse_op_tech.html")

# 2. 定位元素
ctx_zone = driver.find_element(By.ID, "ctxZone")

# 3. 触发右键
ActionChains(driver).context_click(ctx_zone).perform()
time.sleep(0.3)

# 4. 点击右键菜单项
driver.find_element(By.XPATH, '//*[@id="ctxMenu"]//a[text()="打开"]').click()
driver.find_element(By.XPATH, '//*[@id="ctxMenu"]//a[text()="删除"]').click()

# 5. 关闭浏览器
driver.quit()
03 · 双击

双击 double_click(连续两次快速点击)

ActionChains(driver).double_click(el).perform()
双击场景:打开文件(文件管理器)、选中单词/行文本(编辑器)、确认删除(防误触按钮)、表格行展开等。
注意:double_click() 不等价于 click(); sleep(0.1); click(),浏览器有内置的"双击间隔阈值"(通常 300ms 内)。
双击演示:快速双击灯泡开关状态
💡
灯泡状态:关闭
• 单击无效(不会点亮)
• 必须 快速双击 灯泡才切换
• 对应 Selenium:double_click(bulb).perform()
[状态] 等待双击操作...
Python Selenium · 双击 double_click
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains

# 1. 启动浏览器 + 打开演示页面
driver = webdriver.Chrome()
driver.get("https://autotest-505.pages.dev/mouse_op_tech.html")

# 2. 定位灯泡元素
bulb = driver.find_element(By.ID, "bulb")

# 3. 双击 —— 灯泡从关变开 / 从开变关
ActionChains(driver).double_click(bulb).perform()

# 常见场景:双击文件行打开详情
# file_row = driver.find_element(By.XPATH, '//tr[@data-name="report.pdf"]')
# ActionChains(driver).double_click(file_row).perform()

# 4. 关闭浏览器
driver.quit()
04 · 移动(4 种)

鼠标移动

move_to_element / _with_offset / move_by_offset / move_to_point
为什么需要 4 种移动方法?
每种方法的"参考原点"不同:move_to_element 以元素中心为锚点; move_to_element_with_offset 以元素左上角为原点偏移; move_by_offset 以当前鼠标位置为原点; move_to_point 以浏览器视口左上角为绝对坐标原点(Selenium 4.6+)。
选错原点 = 鼠标飞到意想不到的位置!
① move_to_element 移动到元素中心
悬停菜单案例(鼠标移入触发子菜单展开)
② move_to_element_with_offset 元素内相对偏移
画布演示(蓝十字 = 元素中心;鼠标移到画布上,显示相对中心的偏移量)
(+50, 0)
(0, -30)
offset: (0, 0)
③ move_by_offset 相对当前位置移动
小球演示(点击按钮让小球从当前位置相对偏移移动)
每格 25px
↑上
←左
右→
下↓
当前绝对坐标: (center, center)
④ move_to_point 视口绝对坐标(Selenium 4.6+)
坐标地图演示(点击地图任意位置,记录绝对坐标 + 标记十字线)
(0,0)
x →
y ↓
点击地图任意位置 → move_to_point(x, y)
[状态] 请操作上方 4 个移动 demo,日志会显示在此...
Python Selenium · 4 种鼠标移动方法
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains

# 1. 启动浏览器 + 打开演示页面
driver = webdriver.Chrome()
driver.get("https://autotest-505.pages.dev/mouse_op_tech.html")

actions = ActionChains(driver)

# ── ① move_to_element:移动到元素中心 ──
menu = driver.find_element(By.ID, "menuFile")
actions.move_to_element(menu).perform()

# ── ② move_to_element_with_offset:元素内偏移 ──
# 元素左上角为原点,向右 +50px、向上 -30px
canvas = driver.find_element(By.ID, "offsetCanvas")
actions.move_to_element_with_offset(canvas, xoffset=50, yoffset=-30).perform()

# ── ③ move_by_offset:相对当前位置移动 ──
# 鼠标当前位置为原点,向右 +30、向下 +25
actions.move_by_offset(dx=30, dy=25).perform()

# 常见:按住 → 相对移动 → 释放(拖拽 = 分步式)
ball = driver.find_element(By.ID, "ball")
actions.click_and_hold(ball) \
       .move_by_offset(30, 25) \
       .release() \
       .perform()

# ── ④ move_to_point:视口绝对坐标(Selenium 4.6+) ──
# 浏览器视口左上角为原点
actions.move_to_point(x=400, y=300).perform()

# ── 方法对比速查 ──
# move_to_element(el)           锚点: 元素中心       常用度: ★★★★★
# move_to_element_with_offset   锚点: 元素左上角     常用度: ★★★☆☆
# move_by_offset                锚点: 当前鼠标位置   常用度: ★★★★☆(拖拽必备)
# move_to_point                 锚点: 视口左上角     常用度: ★★☆☆☆(4.6+)

# 3. 关闭浏览器
driver.quit()
05 · 按住不松

按住不松 click_and_hold(按下但不释放)

ActionChains(driver).click_and_hold(el).perform()
按住的用途: 拖拽、滑动条拖动、范围选择(按住 Shift 点击)、长按触发上下文菜单等。
注意:click_and_hold() 只按下不释放! 如果之后没有 release(),元素会一直处于"被按下"状态,可能导致后续操作异常。
按住不松演示:按住按钮,进度条持续增长
松手 = 进度停止(当前 0%)
[状态] 按住按钮试试...
Python Selenium · 按住 click_and_hold
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains

# 1. 启动浏览器 + 打开演示页面
driver = webdriver.Chrome()
driver.get("https://autotest-505.pages.dev/mouse_op_tech.html")

# 2. 定位元素
btn = driver.find_element(By.ID, "holdBtn")
actions = ActionChains(driver)

# 3. 按住不松
actions.click_and_hold(btn).perform()

# 在按住期间,可以执行其他操作(例如移动)
actions.move_by_offset(50, 0).perform()

# ★ 重要:最终必须 release 释放!否则会卡住后续操作
actions.release().perform()

# 4. 关闭浏览器
driver.quit()
06 · 释放

释放 release(松开鼠标左键,结束按住/拖拽)

ActionChains(driver).release().perform()
为什么需要单独的 release?
click_and_hold() + release() 组合是"手动版拖拽",比 drag_and_drop 更灵活:
✅ 可以在按住期间 移动到任意坐标(move_by_offset)
✅ 可以 拖后不释放 —— 再拖到另一位置
✅ 可以配合 键盘修饰键(Ctrl / Shift 多选)
典型错误:忘了 release,导致鼠标一直在"被按住"状态。
释放演示:在"按住框"内按住按钮 → 拖到"释放框" → 松开才生效
释放区域(拖到这里松手)
[状态] 试试:按住按钮 → 拖到红色释放框 → 松开...
Python Selenium · 释放 release(分步式拖拽)
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains

# 1. 启动浏览器 + 打开演示页面
driver = webdriver.Chrome()
driver.get("https://autotest-505.pages.dev/mouse_op_tech.html")

# 2. 定位元素
source  = driver.find_element(By.ID, "releaseBtn")
target  = driver.find_element(By.ID, "releaseTarget")
actions = ActionChains(driver)

# ===== 3. 分步式:按住 → 移到目标 → 释放 =====
actions.click_and_hold(source) \
       .move_to_element(target) \
       .release() \
       .perform()

# ===== 按住期间还可以做更多事 =====
actions.click_and_hold(source) \
       .move_by_offset(100, 0) \
       .move_by_offset(0, 80) \
       .release() \
       .perform()

# ★ 总结:ActionChains 7 大方法
# click          左击
# context_click  右击
# double_click   双击
# move_to_element    移动到
# click_and_hold     按住
# drag_and_drop      拖拽(内部 = 按住 + 移动 + 释放)
# release            释放

# 4. 关闭浏览器
driver.quit()
07 · 拖拽(5 种)

鼠标拖拽

drag_and_drop / _by_offset / _with_offset / 分步式 / 贝塞尔曲线
5 种拖拽方法的起点/终点锚点差异:
drag_and_drop(A, B):起点 = 元素 A 中心,终点 = 元素 B 中心(一行式)
drag_and_drop_by_offset(A, dx, dy):起点 = A 中心,终点 = A 中心 + 偏移(滑块验证最爱)
click_and_hold + move_by_offset + release:起点 = A 中心,终点 = 当前鼠标 + 偏移(分步式)
drag_and_drop_with_offset(A, B, dx, dy):起点 = A 中心,终点 = B 中心 + 偏移(Selenium 4.4+)
贝塞尔曲线分步:起点 = A 中心,轨迹 = 多次微偏移 + 抖动(模拟真人行为)
① drag_and_drop 元素 A → 元素 B
一行式演示:把左侧模块拖到右侧目标框
源元素区
用户模块
报表模块
系统设置

Drag
放置目标区
把左侧元素拖到这里
② drag_and_drop_by_offset 元素 → 相对偏移(滑块验证)
滑块演示(拖到最右侧触发"验证通过")
👉 按住滑块向右拖动 →
③ 分步式 click_and_hold + move_by_offset + release 按住 → 偏移 → 释放
自由拖拽演示(把下方拖拽源拖到下方三个分区)
源元素
自由拖拽源
🔴 红色区
🟡 黄色区
🟢 绿色区
④ drag_and_drop_with_offset 元素 → 目标元素内偏移(Selenium 4.4+)
精确落位演示(从左源拖到右侧画布,画布中央蓝色圆 = 目标中心,红点 = 实际落位)
源元素
拖动我

Drag+Off
target 元素内偏移 →
未放置
⑤ 贝塞尔曲线模拟人拖 模拟真实轨迹
滑块演示(手动拖 = 直线轨迹;"模拟人拖" = 带抖动的贝塞尔曲线)
拖动滑块 →
等待拖动...
[状态] 请操作上方 5 种拖拽 demo...
Python Selenium · 5 种拖拽方法
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains

# 1. 启动浏览器 + 打开演示页面
driver = webdriver.Chrome()
driver.get("https://autotest-505.pages.dev/mouse_op_tech.html")

# 2. 定位元素
src  = driver.find_element(By.ID, "drag1")
tgt  = driver.find_element(By.ID, "dropBox")
slider = driver.find_element(By.ID, "slider")

# ── ① drag_and_drop:元素 A → 元素 B(一行式,80% 场景) ──
ActionChains(driver).drag_and_drop(src, tgt).perform()

# ── ② drag_and_drop_by_offset:元素 → 相对偏移(滑块验证最爱) ──
# 把滑块元素从当前位置向右拖 300px、向下 0px
ActionChains(driver).drag_and_drop_by_offset(slider, xoffset=300, yoffset=0).perform()

# ── ③ 分步式:click_and_hold → move_by_offset → release ──
# 更灵活,可中途变速、多次移动、配合键盘
ActionChains(driver) \
   .click_and_hold(src) \
   .move_by_offset(150, 30) \
   .move_by_offset(80, -20) \
   .release() \
   .perform()

# ── ④ drag_and_drop_with_offset:Selenium 4.4+ ──
# 拖到目标元素中心再向右偏移 50px(精确落位)
ActionChains(driver) \
   .drag_and_drop_with_offset(src, tgt, xoffset=50, yoffset=0) \
   .perform()

# ── ⑤ 贝塞尔曲线分步:模拟真人行为 ──
import random, math

def bezier_drag(driver, src, dx, dy, steps=30):
    actions = ActionChains(driver)
    actions.click_and_hold(src)
    for i in range(steps):
        t = i / steps
        # 二次贝塞尔,带随机抖动
        step_dx = dx/steps + random.uniform(-2, 2)
        step_dy = dy/steps + random.uniform(-1, 1)
        actions.move_by_offset(step_dx, step_dy)
    actions.release().perform()

bezier_drag(driver, slider, dx=300, dy=0)

# ── 方法对比速查 ──
# 方法                              起点锚点        终点锚点
# drag_and_drop(A, B)              A 中心          B 中心          ★★★★★
# drag_and_drop_by_offset(A,dx,dy) A 中心          A 中心+偏移     ★★★★☆ 滑块验证
# click_and_hold + move_by_offset  A 中心          当前鼠标+偏移   ★★★★☆ 分步灵活
# drag_and_drop_with_offset        A 中心          B 中心+偏移     ★★☆☆☆ 4.4+
# 贝塞尔曲线分步                   A 中心          多点偏移轨迹     ★★★☆☆ 反爬

# 3. 关闭浏览器
driver.quit()
08 · 滚动(3 种)

鼠标滚动

scroll_by_amount / scroll_to_element / scroll_to_element_with_offset
什么时候需要滚动?
页面太长元素在屏幕外无法交互、滑块验证需滚动到指定位置、懒加载页面需先滚动触发内容加载。Selenium 4.2 提供原生 scroll_by_amount() 等方法,比旧版 driver.execute_script("window.scrollBy...") 更稳定。
三种方法的"参考原点":scroll_by_amount 以当前视口为原点滚动;scroll_to_element 以元素边界自动对齐;scroll_to_element_with_offset 在滚到元素的基础上再加偏移,最适合避开固定导航栏遮挡。
① scroll_by_amount 按像素偏移量滚动
演示:长列表 + 多种偏移量滚动
条目 01 · 需要滚动才能看到下面的目标元素 👇
条目 02
条目 03
条目 04
条目 05
条目 06
条目 07
条目 08
条目 09
条目 10
条目 11
条目 12
条目 13
条目 14
条目 15
条目 16
条目 17
条目 18
条目 19
条目 20 · 滚到底了
scrollTop: 0 scrollHeight: 0
② scroll_to_element 滚到元素完全可见
演示:自动滚动直到目标元素可见(绿色高亮标记)
条目 01
条目 02
条目 03
条目 04
条目 05
条目 06
条目 07
条目 08
条目 09
条目 10
条目 11
条目 12
条目 13
条目 14
🎯 目标元素(scroll_to_element 会滚到我这里)
注意:scroll_to_element() 会把元素滚到视口底部对齐。如果页面有 position:fixed 的顶部导航栏,元素上半部分会被挡住。这种情况请用 ③ scroll_to_element_with_offset 。
③ scroll_to_element_with_offset 滚到元素 + 偏移微调
演示:先滚到目标元素,再额外向上/向下偏移,避开固定导航栏遮挡
条目 01
条目 02
条目 03
条目 04
条目 05
条目 06
条目 07
条目 08
条目 09
条目 10
条目 11
条目 12
条目 13
条目 14
🎯 目标元素(加偏移后会更居中)
[状态] 请操作上方 3 个滚动 demo,日志会显示在此...
Python Selenium · 3 种滚动方法
# -*- coding: utf-8 -*-
# scroll.py —— Selenium 原生滚动 API 完整演示
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
import time

driver = webdriver.Chrome()
driver.get("https://autotest-505.pages.dev/mouse_op_tech.html")
actions = ActionChains(driver)

# ── ① scroll_by_amount(dx, dy) ──────────────────────
# 按像素偏移量滚动(正=向下/向右,负=向上/向左)
actions.scroll_by_amount(0, 500).perform()    # 向下滚 500px
time.sleep(1)
actions.scroll_by_amount(0, -300).perform()   # 向上滚 300px

# ── ② scroll_to_element(target) ────────────────────
# 滚动直到目标元素完全可见(底部对齐视口)
target = driver.find_element(By.ID, "submit-btn")
actions.scroll_to_element(target).perform()

# ── ③ scroll_to_element_with_offset(target, dx, dy) ──
# 滚到元素后再加偏移微调(最常用:避开固定导航栏遮挡)
actions.scroll_to_element_with_offset(target, 0, -80).perform()
# 元素上方额外留 80px 间距,避开 70px 高的顶部导航栏

# ── 旧版兼容方案(JavaScript 注入) ──────────────────
# Selenium 4.1 及以下版本没有原生 scroll_by_amount
driver.execute_script("window.scrollBy(0, 500)")
driver.execute_script("arguments[0].scrollIntoView()", target)

# ── 方法对比速查 ──
# scroll_by_amount(dx, dy)           锚点: 当前视口     常用度: ★★★☆☆
# scroll_to_element(target)           锚点: 元素边界     常用度: ★★★★☆
# scroll_to_element_with_offset       锚点: 元素+偏移    常用度: ★★★★★(避遮挡必备)

# 2. 关闭浏览器
driver.quit()
打开 查看属性 复制
重命名 删除

关于我们

Python 自动化测试学习平台是一个面向软件测试工程师、开发人员及在校学生的交互式在线学习平台,专注于 Selenium WebDriver 与 Python unittest 自动化测试技能的教学与实践。

我们以"理论 + 实战 + 可交互演示"为核心特色,将八种常规元素定位和Javascript定位、元素操作、自动化测试工具、单元测试、测试模型等知识体系拆分为模块化课程,每个模块都配有可点击、可输入、可运行的模拟练习页面。

平台致力于降低自动化测试的入门门槛,让学习者从"看懂代码"到"动手实操",逐步掌握企业级自动化测试框架的设计与落地能力。

联系方式

📧邮箱:lq@selenium-auto-test.com

📞电话:0755-12345678

📍地址:深圳

💬微信公众号:Selenium自动化测试

🐙GitHub:github.com/selenium-auto-test

免责声明

1. 本平台提供的所有内容(包括但不限于代码示例、演示页面、理论讲解)均仅供学习与参考使用,不构成任何商业建议或保证。

2. 学习者通过本平台所获取的任何信息、代码或实践经验,应结合自身实际情况进行独立判断和应用。

3. 本平台不保证内容的绝对准确性、完整性或时效性,也不对因使用本平台内容而产生的任何直接或间接损失承担责任。

4. 本平台所引用的第三方库(Selenium、ChromeDriver、unittest 等)版权归其各自作者及维护者所有。

5. 如涉及版权问题或内容建议,请及时通过联系方式与我们沟通,我们将第一时间处理。