Skip to content Skip to sidebar Skip to footer

Python Random Mouse Movements

I would like to make random mouse movements in specified rectangle area (limited with coordinates x1, y1, x2, y2, x3, y3, x4, y4). Movements should be smooth, random, not just str

Solution 1:

This code works on Windows only. You can experiment with the parameters inside the random_movement function to get better results. Good luck!

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

Example:

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

Solution 2:

For random smooth movements constrained to a rectangle I'd try to use Lissajous curves with randomly changing coefficients.

Solution 3:

I made this based on Piotr Dabkowski's code, with some extra features (taking random breaks, random scrolls, and users can end early by right clicking). This works for Python 3, and again, for Windows only.

import ctypes
import random
import time
import math
import win32gui

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

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

defmove_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)

defstart(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)):

    defget_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.0print('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 clickwhile (not right_clicked) and (time.time() < endtime):
        if ctypes.windll.user32.GetKeyState(0x02) notin [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 loopwhile (not right_clicked) and (time.time() < break_endtime):
                if ctypes.windll.user32.GetKeyState(0x02) notin [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 = -1if sign < 0.5else1if (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] inrange(*x_bound)) and (pos[1] inrange(*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 insideif inside_boundary:
            while new_pos[0] notinrange(*x_bound) or new_pos[1] notinrange(*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)

Solution 4:

For performing the movements there is a third-party package call PyUserInput that will allow you to control mouse or keyboard, and it is cross-platform. Install it using pip:

$ pip install PyUserInput

For doing smooth movements you can try what 9000 proposes in his answer.

Post a Comment for "Python Random Mouse Movements"