python 随机鼠标移动
我想在一个指定的矩形区域内随机移动鼠标,这个区域是由坐标 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))