python random mouse movements

Question:

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 straight lines, go randomly up/down/left/right/etc for specified time duration.

Could you give me a hand or working example I can learn from?
many thanks

Asked By: peter

||

Answers:

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

Answered By: 9000

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.

Answered By: jabaldonedo

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))
Answered By: Piotr Dabkowski

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)

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)
Answered By: newbee

Here is a demo of random X,Y positions you can play as your requirements:

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

Note: install first

pip3 install pyautogui

Answered By: Ricardo De Leon
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.