本页面是 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 代码(一键复制)。
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 等把鼠标送到位
el.click() 或 ActionChains(driver).click(el).perform()
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()
element.click() 触发右键,必须用 ActionChains.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()
double_click() 不等价于 click(); sleep(0.1); click(),浏览器有内置的"双击间隔阈值"(通常 300ms 内)。
double_click(bulb).perform()
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()
move_to_element 以元素中心为锚点;
move_to_element_with_offset 以元素左上角为原点偏移;
move_by_offset 以当前鼠标位置为原点;
move_to_point 以浏览器视口左上角为绝对坐标原点(Selenium 4.6+)。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()
click_and_hold() 只按下不释放!
如果之后没有 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. 定位元素 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()
drag_and_drop 更灵活:move_by_offset)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()
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 中心,轨迹 = 多次微偏移 + 抖动(模拟真人行为)
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()
scroll_by_amount() 等方法,比旧版 driver.execute_script("window.scrollBy...") 更稳定。scroll_by_amount 以当前视口为原点滚动;scroll_to_element 以元素边界自动对齐;scroll_to_element_with_offset 在滚到元素的基础上再加偏移,最适合避开固定导航栏遮挡。
# -*- 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()