You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python实现基于WindMouse算法的类人鼠标移动?

实现遵循WindMouse算法的逼真鼠标移动

我不确定当前问题表述是否准确,想咨询是否可通过pyautogui、Selenium Actions或其他工具,让Python控制的所有鼠标移动都遵循WindMouse算法?我希望为自制机器人实现尽可能逼真的鼠标移动,若可行该如何操作?

核心结论

完全可以实现。WindMouse算法的核心是生成模拟人类行为的鼠标路径点,只需将不同工具的鼠标移动函数作为回调传入WindMouse的move_mouse参数即可。以下是针对不同工具的具体实现方案:

1. 使用PyAutoGUI实现

PyAutoGUI适合桌面级鼠标控制,只需将其moveTo函数作为回调传入WindMouse,分步执行路径点移动:

首先安装依赖:

pip install pyautogui numpy

实现代码:

import numpy as np
import pyautogui
import time

sqrt3 = np.sqrt(3)
sqrt5 = np.sqrt(5)

def wind_mouse(start_x, start_y, dest_x, dest_y, G_0=9, W_0=3, M_0=15, D_0=12, move_mouse=lambda x,y: None):
    current_x,current_y = start_x,start_y
    v_x = v_y = W_x = W_y = 0
    while (dist:=np.hypot(dest_x-start_x,dest_y-start_y)) >= 1:
        W_mag = min(W_0, dist)
        if dist >= D_0:
            W_x = W_x/sqrt3 + (2*np.random.random()-1)*W_mag/sqrt5
            W_y = W_y/sqrt3 + (2*np.random.random()-1)*W_mag/sqrt5
        else:
            W_x /= sqrt3
            W_y /= sqrt3
            if M_0 < 3:
                M_0 = np.random.random()*3 + 3
            else:
                M_0 /= sqrt5
        v_x += W_x + G_0*(dest_x-start_x)/dist
        v_y += W_y + G_0*(dest_y-start_y)/dist
        v_mag = np.hypot(v_x, v_y)
        if v_mag > M_0:
            v_clip = M_0/2 + np.random.random()*M_0/2
            v_x = (v_x/v_mag) * v_clip
            v_y = (v_y/v_mag) * v_clip
        start_x += v_x
        start_y += v_y
        move_x = int(np.round(start_x))
        move_y = int(np.round(start_y))
        if current_x != move_x or current_y != move_y:
            move_mouse(current_x:=move_x,current_y:=move_y)
            time.sleep(0.01)  # 模拟人类移动间隔
    return current_x,current_y

# 封装成PyAutoGUI调用函数
def pyautogui_wind_move(to_x, to_y):
    start_x, start_y = pyautogui.position()
    wind_mouse(start_x, start_y, to_x, to_y, move_mouse=pyautogui.moveTo)

# 示例:移动到屏幕(500,500)位置
pyautogui_wind_move(500, 500)

2. 使用Selenium Actions实现

Selenium用于浏览器内的鼠标控制,需将WindMouse生成的路径转为相对位移,通过move_by_offset执行:

首先安装依赖:

pip install selenium numpy

实现代码:

import numpy as np
import time
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

sqrt3 = np.sqrt(3)
sqrt5 = np.sqrt(5)

def wind_mouse(start_x, start_y, dest_x, dest_y, G_0=9, W_0=3, M_0=15, D_0=12, move_mouse=lambda dx,dy: None):
    current_x,current_y = start_x,start_y
    v_x = v_y = W_x = W_y = 0
    while (dist:=np.hypot(dest_x-start_x,dest_y-start_y)) >= 1:
        W_mag = min(W_0, dist)
        if dist >= D_0:
            W_x = W_x/sqrt3 + (2*np.random.random()-1)*W_mag/sqrt5
            W_y = W_y/sqrt3 + (2*np.random.random()-1)*W_mag/sqrt5
        else:
            W_x /= sqrt3
            W_y /= sqrt3
            if M_0 < 3:
                M_0 = np.random.random()*3 + 3
            else:
                M_0 /= sqrt5
        v_x += W_x + G_0*(dest_x-start_x)/dist
        v_y += W_y + G_0*(dest_y-start_y)/dist
        v_mag = np.hypot(v_x, v_y)
        if v_mag > M_0:
            v_clip = M_0/2 + np.random.random()*M_0/2
            v_x = (v_x/v_mag) * v_clip
            v_y = (v_y/v_mag) * v_clip
        start_x += v_x
        start_y += v_y
        move_x = int(np.round(start_x))
        move_y = int(np.round(start_y))
        if current_x != move_x or current_y != move_y:
            dx = move_x - current_x
            dy = move_y - current_y
            move_mouse(dx, dy)
            current_x, current_y = move_x, move_y
            time.sleep(0.01)
    return current_x,current_y

# 封装成Selenium调用函数
def selenium_wind_move(driver, to_x, to_y):
    action = ActionChains(driver)
    action.move_by_offset(0,0).perform()  # 重置坐标原点为当前鼠标位置
    start_x, start_y = 0, 0
    
    def selenium_move(dx, dy):
        action.move_by_offset(dx, dy).perform()
    
    wind_mouse(start_x, start_y, to_x, to_y, move_mouse=selenium_move)

# 示例用法
driver = webdriver.Chrome()
driver.get("https://example.com")
# 移动到页面视口内(300, 200)位置
selenium_wind_move(driver, 300, 200)

3. 使用pynput实现

pynput支持系统级鼠标控制,适合更底层的桌面自动化场景:

首先安装依赖:

pip install pynput numpy

实现代码:

import numpy as np
import time
from pynput.mouse import Controller

sqrt3 = np.sqrt(3)
sqrt5 = np.sqrt(5)

def wind_mouse(start_x, start_y, dest_x, dest_y, G_0=9, W_0=3, M_0=15, D_0=12, move_mouse=lambda x,y: None):
    current_x,current_y = start_x,start_y
    v_x = v_y = W_x = W_y = 0
    while (dist:=np.hypot(dest_x-start_x,dest_y-start_y)) >= 1:
        W_mag = min(W_0, dist)
        if dist >= D_0:
            W_x = W_x/sqrt3 + (2*np.random.random()-1)*W_mag/sqrt5
            W_y = W_y/sqrt3 + (2*np.random.random()-1)*W_mag/sqrt5
        else:
            W_x /= sqrt3
            W_y /= sqrt3
            if M_0 < 3:
                M_0 = np.random.random()*3 + 3
            else:
                M_0 /= sqrt5
        v_x += W_x + G_0*(dest_x-start_x)/dist
        v_y += W_y + G_0*(dest_y-start_y)/dist
        v_mag = np.hypot(v_x, v_y)
        if v_mag > M_0:
            v_clip = M_0/2 + np.random.random()*M_0/2
            v_x = (v_x/v_mag) * v_clip
            v_y = (v_y/v_mag) * v_clip
        start_x += v_x
        start_y += v_y
        move_x = int(np.round(start_x))
        move_y = int(np.round(start_y))
        if current_x != move_x or current_y != move_y:
            move_mouse(current_x:=move_x,current_y:=move_y)
            time.sleep(0.01)
    return current_x,current_y

# 封装成pynput调用函数
def pynput_wind_move(to_x, to_y):
    mouse = Controller()
    start_x, start_y = mouse.position
    wind_mouse(start_x, start_y, to_x, to_y, move_mouse=lambda x,y: setattr(mouse, 'position', (x,y)))

# 示例:移动到屏幕(600, 400)位置
pynput_wind_move(600, 400)

优化提示

  • 调整WindMouse的参数(G_0、W_0等)可以改变移动风格:增大W_0会让路径更随机,减小则更平滑;调整M_0可以控制最大移动步长。
  • 增加的time.sleep(0.01)是模拟人类鼠标移动的间隔,可根据需求微调时长。

内容的提问来源于stack exchange,提问作者heyitme

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 03:25:21