【问题标题】:python random mouse movementspython随机鼠标移动
【发布时间】:2023-03-30 00:41:01
【问题描述】:

我想在指定的矩形区域内随机移动鼠标(限于坐标 x1、y1、x2、y2、x3、y3、x4、y4)。 运动应该是平滑的、随机的,而不仅仅是直线,在指定的持续时间内随机向上/向下/向左/向右/等。

您能给我一个帮助或工作示例,我可以从中学习吗? 非常感谢

【问题讨论】:

  • 控制鼠标指针是高度特定于平台的。你用的是什么平台?

标签: python python-2.7


【解决方案1】:

此代码仅适用于 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))

【讨论】:

  • 酷! :) 非常感谢。我将从这个例子中学到一些东西。
  • 为什么在xy 分配中使用65536L
  • uint16 是从 0 到 65535。0 表示最左边,65535 最右边。
【解决方案2】:

对于受限于矩形的随机平滑运动,我会尝试使用带有随机变化系数的Lissajous curves

【讨论】:

  • 感谢它看起来不错。但我想做随机的鼠标移动(例如,当你在屏幕上移动鼠标时,你永远不会得到相同的移动。所以我不需要“漂亮”的曲线,它应该只模拟用户的鼠标)。不幸的是,我不是 python 英雄,所以任何例子都受到高度赞赏。谢谢
【解决方案3】:

我根据 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)

【讨论】:

    【解决方案4】:

    为了执行动作,有一个第三方包调用PyUserInput 可以让你控制鼠标或键盘,它是跨平台的。使用 pip 安装它:

    $ pip install PyUserInput
    

    为了做流畅的动作,你可以试试 9000 在他的回答中提出的建议。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-03
      相关资源
      最近更新 更多