python 随机鼠标移动

3 投票
5 回答
15120 浏览
提问于 2025-04-18 00:49

我想在一个指定的矩形区域内随机移动鼠标,这个区域是由坐标 x1, y1, x2, y2, x3, y3, x4, y4 限定的。

这些移动应该是平滑的、随机的,不仅仅是直线,而是可以随机向上、向下、向左、向右等,持续一段时间。

你能帮我一下,或者给我一个可以学习的示例吗?非常感谢!

5 个回答

-1

要实现这些动作,可以使用一个叫做 PyUserInput 的第三方包,它可以让你控制鼠标或键盘,而且支持多种操作系统。你可以通过 pip 来安装它:

$ pip install PyUserInput

如果想要让动作更流畅,可以试试9000在他的回答中提到的方法。

0

我根据Piotr Dabkowski的代码做了这个,并添加了一些额外的功能,比如随机休息、随机滚动,用户还可以通过右键点击提前结束。这段代码适用于Python 3,而且只在Windows系统上运行。

import ctypes
import random
import time
import math
import win32gui

xmax = ctypes.windll.user32.GetSystemMetrics(0) 
ymax = ctypes.windll.user32.GetSystemMetrics(1)

def get_position():
    _, _, (x,y) = win32gui.GetCursorInfo()
    return (x,y)

def move_mouse(pos):
    x_pos, y_pos = pos
    x = int(65536 * x_pos / xmax + 1)
    y = int(65536 * y_pos / ymax + 1)
    return ctypes.windll.user32.mouse_event(32769, x, y, 0, 0)

def start(t=30, min_speed=10, max_speed=500, x_bound=[0,xmax], y_bound=[0,ymax],
    p_break = 0.005, break_range = (10, 60), p_scroll = 0.01, scroll_range = (100, 1000)):

    def get_new_speed(min_val, max_val, val, delta=0.01):
        new_val = val + random.randrange(-1,2)*(max_val-min_val)*delta
        if new_val<min_val or new_val>max_val:
            return get_new_speed(min_val, max_val, val, delta)
        return new_val

    steps_per_second = 35.0 

    print('Started.')
    endtime = time.time() + int(t*60)

    # Initialize position, speed and direction
    pos = get_position()
    speed = min_speed + random.random()*(max_speed-min_speed)
    direction = 2*math.pi*random.random()
    inside_boundary = False
    right_clicked = False

    # Keep moving mouse until end time, or until right click
    while (not right_clicked) and (time.time() < endtime):
        if ctypes.windll.user32.GetKeyState(0x02) not in [0,1]:
            right_clicked = True

        time.sleep(1.0/steps_per_second)

        # Taking a break of random duration
        duration = random.randint(*break_range) # in unit of seconds
        break_endtime = time.time() + duration
        r = random.random()
        if (1-p_break) <= r < 1:
            # Keep checking for right click to exit loop
            while (not right_clicked) and (time.time() < break_endtime):
                if ctypes.windll.user32.GetKeyState(0x02) not in [0,1]:
                    right_clicked = True
                time.sleep(1.0/steps_per_second)
                time_left = break_endtime - time.time()
                print('Paused %d / %ds' % (time_left,duration) + ' '*50, end='\r')
            pos = get_position()
            print(' '*50, end='\r')

        # Random scroll
        r = random.random()
        lines = random.randint(*scroll_range)
        sign = random.random()
        sign = -1 if sign < 0.5 else 1
        if (1-p_scroll) <= r < 1:
            time.sleep(random.random())
            ctypes.windll.user32.mouse_event(2048, 0, 0, sign*lines, 0)
            time.sleep(random.random())
            pos = get_position()

        # Random move
        move_mouse(pos)

        time_left = endtime - time.time()
        print('Running (time left: %ds)' % time_left + ' '*50, end='\r')

        if (pos[0] in range(*x_bound)) and (pos[1] in range(*y_bound)):
            inside_boundary = True

        # Update position, speed and direction
        speed = get_new_speed(min_speed, max_speed, speed)
        direction+=random.randrange(-1,2)*math.pi/5.0*random.random()
        new_pos = (int(round(pos[0]+speed*math.cos(direction)/steps_per_second)),
               int(round(pos[1]+speed*math.sin(direction)/steps_per_second)))
        # Once mouse position is inside boundary, new position must also be inside
        if inside_boundary:
            while new_pos[0] not in range(*x_bound) or new_pos[1] not in range(*y_bound):
                direction  = 2*math.pi*random.random()
                new_pos = (int(round(pos[0]+speed*math.cos(direction)/steps_per_second)),
                   int(round(pos[1]+speed*math.sin(direction)/steps_per_second)))
        pos=new_pos
    print('Stopped.' + ' ' * 50)
1

对于在一个矩形区域内随机平滑移动的情况,我会尝试使用利萨如曲线,并随机改变它的参数。

2

这里有一个随机生成X、Y坐标的示例,你可以根据自己的需求来使用:

from time import sleep
import pyautogui
import numpy as np

# Check your screen size
print(pyautogui.size())

count=0
while count<1000:
     x=np.random.randint(1,1792)
     y=np.random.randint(1,1120)
     pyautogui.moveTo(x, y)
     print(x)
     print(y)
     sleep(20)
     count+=1

注意:请先安装

使用命令:pip3 install pyautogui

4

这段代码只在Windows系统上能运行。你可以试着调整random_movement函数里的参数,这样可能会得到更好的效果。祝你好运!

import ctypes
import random
import time
import math

def move_mouse(pos):
    x_pos, y_pos = pos
    screen_size = ctypes.windll.user32.GetSystemMetrics(0), ctypes.windll.user32.GetSystemMetrics(1)
    x = 65536L * x_pos / screen_size[0] + 1
    y = 65536L * y_pos / screen_size[1] + 1
    return ctypes.windll.user32.mouse_event(32769, x, y, 0, 0)

def random_movement(top_left_corner, bottom_right_corner, min_speed=100, max_speed=200):
    '''speed is in pixels per second'''

    x_bound = top_left_corner[0], bottom_right_corner[0]
    y_bound = top_left_corner[1], bottom_right_corner[1]

    pos = (random.randrange(*x_bound),
                    random.randrange(*y_bound))

    speed = min_speed + random.random()*(max_speed-min_speed)
    direction = 2*math.pi*random.random()

    def get_new_val(min_val, max_val, val, delta=0.01):
        new_val = val + random.randrange(-1,2)*(max_val-min_val)*delta
        if new_val<min_val or new_val>max_val:
            return get_new_val(min_val, max_val, val, delta)
        return new_val

    steps_per_second = 35.0
    while True:
        move_mouse(pos)
        time.sleep(1.0/steps_per_second) 

        speed = get_new_val(min_speed, max_speed, speed)
        direction+=random.randrange(-1,2)*math.pi/5.0*random.random()

        new_pos = (int(round(pos[0]+speed*math.cos(direction)/steps_per_second)),
               int(round(pos[1]+speed*math.sin(direction)/steps_per_second)))

        while new_pos[0] not in xrange(*x_bound) or new_pos[1] not in xrange(*y_bound):
            direction  = 2*math.pi*random.random()
            new_pos = (int(round(pos[0]+speed*math.cos(direction)/steps_per_second)),
               int(round(pos[1]+speed*math.sin(direction)/steps_per_second)))
        pos=new_pos

示例:

random_movement((300,300),(600,600))

撰写回答