昌邑做网站的公司,长沙cms模板建站,网站建设要架服务器,网站备案全国合作拍照点Python自动化(3)——鼠标模拟
前台鼠标模拟
鼠标模拟和键盘模拟类似#xff0c;也是分前台和后台模拟。话不多说直接#xff0c;上代码#xff1a;
import time
import win32api
import win32con
import win32gui
from ctypes import *MOUSEEVENTF_LEFTDOWN 0x2
MOUSEEV…Python自动化(3)——鼠标模拟
前台鼠标模拟
鼠标模拟和键盘模拟类似也是分前台和后台模拟。话不多说直接上代码
import time
import win32api
import win32con
import win32gui
from ctypes import *MOUSEEVENTF_LEFTDOWN 0x2
MOUSEEVENTF_LEFTUP 0x4
MOUSEEVENTF_MIDDLEDOWN 0x20
MOUSEEVENTF_MIDDLEUP 0x40
MOUSEEVENTF_RIGHTDOWN 0x8
MOUSEEVENTF_RIGHTUP 0x10
MOUSEEVENTF_MOVE 0x1class FrontstageMouse():def __init__(self):print(FrontstageMouse init)def bind(self, hwnd):self.hwnd hwnddef getRelativePosition(self, x, y):left, top, right, bottom win32gui.GetWindowRect(self.hwnd)return [left x, top y]# 前台模拟方法1——使用win32api.mouse_event默认 ############################################# 模拟鼠标的按键按下def clickDown(self, x, y, buttonl):win32api.SetCursorPos(self.getRelativePosition(int(x), int(y)))button button.lower()if button l:win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0,0,0)elif button m:win32api.mouse_event(win32con.MOUSEEVENTF_MIDDLEDOWN,0,0,0,0)elif button r:win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTDOWN,0,0,0,0)print(clickDown x: str(x) , y: str(y))# 模拟鼠标的按键抬起def clickUp(self, x, y, buttonl):win32api.SetCursorPos(self.getRelativePosition(int(x), int(y)))button button.lower()if button l:win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0,0,0)elif button m:win32api.mouse_event(win32con.MOUSEEVENTF_MIDDLEUP,0,0,0,0)elif button r:win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP,0,0,0,0)print(clickUp x: str(x) , y: str(y))# 模拟鼠标的点击def click(self, x, y, buttonl, interval0.1):win32api.SetCursorPos(self.getRelativePosition(int(x), int(y)))button button.lower()if button l:win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0,0,0)time.sleep(interval)win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0,0,0)elif button m:win32api.mouse_event(win32con.MOUSEEVENTF_MIDDLEDOWN,0,0,0,0)time.sleep(interval)win32api.mouse_event(win32con.MOUSEEVENTF_MIDDLEUP,0,0,0,0)elif button r:win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTDOWN,0,0,0,0)time.sleep(interval)win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP,0,0,0,0)print(clicked x: str(x) , y: str(y))# 模拟鼠标的左键双击def doubleClick(self, x, y):win32api.SetCursorPos(self.getRelativePosition(int(x), int(y)))win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0,0,0)win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0,0,0)time.sleep(0.05)win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0,0,0)win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0,0,0)print(doubleClick x: str(x) , y: str(y))# 模拟鼠标的左键拖动(即在第一个点按下拖动至第二个点抬起# 但是不知道为啥实际上是不准的滑动的值会比实际的多2倍左右因此默认除以2# 有时候会误触导致滑动改成点击def slide(self, x1, y1, x2, y2):# win32api.SetCursorPos(self.getRelativePosition(int(x1), int(y1)))time.sleep(0.1)offsetX int(x2)/2 - int(x1)/2offsetY int(y2)/2 - int(y1)/2print(offsetX: str(offsetX))print(offsetY: str(offsetY))win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0,0,0)time.sleep(0.1)win32api.mouse_event(win32con.MOUSEEVENTF_MOVE, int(offsetX), int(offsetY))time.sleep(0.1)win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0,0,0)print(slide x1: str(x1) , y1: str(y1) , x2: str(x2) , y2: str(y2))# 前台模拟方法2——使用ctypes ############################################# 模拟鼠标的按键按下def clickDown_2(self, x, y, buttonl):win32api.SetCursorPos(self.getRelativePosition(int(x), int(y)))button button.lower()if button l:windll.user32.mouse_event(MOUSEEVENTF_LEFTDOWN)elif button m:windll.user32.mouse_event(MOUSEEVENTF_MIDDLEDOWN)elif button r:windll.user32.mouse_event(MOUSEEVENTF_RIGHTDOWN)print(clickDown_2 x: str(x) , y: str(y))# 模拟鼠标的按键抬起def clickUp_2(self, x, y, buttonl):win32api.SetCursorPos(self.getRelativePosition(int(x), int(y)))button button.lower()if button l:windll.user32.mouse_event(MOUSEEVENTF_LEFTUP)elif button m:windll.user32.mouse_event(MOUSEEVENTF_MIDDLEUP)elif button r:windll.user32.mouse_event(MOUSEEVENTF_RIGHTUP)print(clickUp_2 x: str(x) , y: str(y))# 模拟鼠标左键单击def click_2(self, x, y, buttonl, interval0.05):win32api.SetCursorPos(self.getRelativePosition(int(x), int(y)))button button.lower()if button l:windll.user32.mouse_event(MOUSEEVENTF_LEFTDOWN)time.sleep(interval)windll.user32.mouse_event(MOUSEEVENTF_LEFTUP)elif button m:windll.user32.mouse_event(MOUSEEVENTF_MIDDLEDOWN)time.sleep(interval)windll.user32.mouse_event(MOUSEEVENTF_MIDDLEUP)elif button r:windll.user32.mouse_event(MOUSEEVENTF_RIGHTDOWN)time.sleep(interval)windll.user32.mouse_event(MOUSEEVENTF_RIGHTUP)print(clicked_2 x: str(x) , y: str(y))# 模拟鼠标的左键双击def doubleClick_2(self, x, y):win32api.SetCursorPos(self.getRelativePosition(int(x), int(y)))windll.user32.mouse_event(MOUSEEVENTF_LEFTDOWN)time.sleep(0.05)windll.user32.mouse_event(MOUSEEVENTF_LEFTUP)time.sleep(0.05)windll.user32.mouse_event(MOUSEEVENTF_LEFTDOWN)time.sleep(0.05)windll.user32.mouse_event(MOUSEEVENTF_LEFTUP)print(doubleClick_2 x: str(x) , y: str(y))def slide_2(self, x1, y1, x2, y2):# win32api.SetCursorPos(self.getRelativePosition(int(x1), int(y1)))time.sleep(0.1)offsetX int(x2)/2 - int(x1)/2offsetY int(y2)/2 - int(y1)/2print(offsetX: str(offsetX))print(offsetY: str(offsetY))win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0,0,0)time.sleep(0.1)win32api.mouse_event(win32con.MOUSEEVENTF_MOVE, int(offsetX), int(offsetY))time.sleep(0.1)win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0,0,0)print(slide x1: str(x1) , y1: str(y1) , x2: str(x2) , y2: str(y2))这里使用了两个不同的库分别实现分别是win32api和ctypes库。win32库实际上也是实现鼠标后台模拟的关键也可以实现前台模拟使用mouse_event方法。 其中win32api中mouse_event的函数原型 VOID mouse_eventDWORD dwFlagsDWORD dxDWORD dwFlagsOWORD dxDWORD dy DWORD dwData DWORD dwExtralnfo dwFlags标志位集指定点击按钮和鼠标动作的多种情况。此参数里的各位可以是下列值的任何合理组合 MOOSE_EVENTF_ABSOLOTE表明参数dXdy含有规范化的绝对坐标。如果不设置此位参数含有相对数据相对于上次位置的改动位置。此标志可被设置也可不设置不管鼠标的类型或与系统相连的类似于鼠标的设备的类型如何。要得到关于相对鼠标动作的信息参见下面备注部分。 MOOSEEVENTFMOVE表明发生移动。 M00SEEVENTF_LEFTDOWN表明接按下鼠标左键。 M00SEEVENTF_LEFTUP表明松开鼠标左键。 MOOSEEVENTF_RIGHTDOWN表明按下鼠标右键。 MOOSEEVENTF_RIGHTUP表明松开鼠标右键。 MOOSEEVENTF_MIDDLEDOWN表明按下鼠标中键。 MOOSEEVENTF_MIDDLEUP表明松开鼠标中键。 MOOSEEVENTF_WHEEL在Windows NT中如果鼠标有一个轮表明鼠标轮被移动。移动的数量由dwData给出。 dx指定鼠标沿x轴的绝对位置或者从上次鼠标事件产生以来移动的数量依赖于MOOSEEVENTF_ABSOLOTE的设置。给出的绝对数据作为鼠标的实际X坐标给出的相对数据作为移动的mickeys数。一个mickey表示鼠标移动的数量表明鼠标已经移动。 dy指定鼠标沿y轴的绝对位置或者从上次鼠标事件产生以来移动的数量依赖于MOOSEEVENTF_ABSOLVTE的设置。给出的绝对数据作为鼠标的实际y坐标给出的相对数据作为移动的mickeys数。 dwData如果dwFlags为MOOSEEVENTF_WHEEL则dwData指定鼠标轮移动的数量。正值表明鼠标轮向前转动即远离用户的方向负值表明鼠标轮向后转动即朝向用户。一个轮击定义为WHEEL_DELTA即120。 如果dwFlagsS不是MOOSEEVENTF_WHEEL则dWData应为零。 dwExtralnfo指定与鼠标事件相关的附加32位值。应用程序调用函数GetMessgeExtrajnfo来获得此附加信息。 返回值无。
后台鼠标模拟
import time
import win32api
import win32con
import win32com
import win32gui
import pythoncom
import mathclass BackstageMouse():def __init__(self):print(BackstageMouse init)def bind(self, hwnd):self.hwnd hwnd# 聚焦句柄对应的窗口def focusHwnd(self):pythoncom.CoInitialize()shell win32com.client.Dispatch(WScript.Shell)shell.SendKeys(%)win32gui.SetForegroundWindow(self.hwnd)# 后台模拟方法1——使用SendMessage默认 ############################################# 模拟鼠标的移动def move(self, x, y):point win32api.MAKELONG(int(x), int(y))win32api.SendMessage(self.hwnd, win32con.WM_MOUSEMOVE, win32con.MK_LBUTTON, point)# 模拟鼠标的按键按下def clickDown(self, x, y, buttonl):point win32api.MAKELONG(int(x), int(y))button button.lower()if button l:win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, point)elif button m:win32api.SendMessage(self.hwnd, win32con.WM_MBUTTONDOWN, win32con.MK_MBUTTON, point)elif button r:win32api.SendMessage(self.hwnd, win32con.WM_RBUTTONDOWN, win32con.MK_RBUTTON, point)print(clickDown x: str(x) , y: str(y))# 模拟鼠标的按键抬起def clickUp(self, x, y, buttonl):point win32api.MAKELONG(int(x), int(y))button button.lower()if button l:win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, point)elif button m:win32api.SendMessage(self.hwnd, win32con.WM_MBUTTONUP, win32con.MK_MBUTTON, point)elif button r:win32api.SendMessage(self.hwnd, win32con.WM_RBUTTONUP, win32con.MK_RBUTTON, point)print(clickUp x: str(x) , y: str(y))# 模拟鼠标的点击def click(self, x, y, buttonl, interval0.1):point win32api.MAKELONG(int(x), int(y))button button.lower()if button l:win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, point)time.sleep(interval)win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, point)elif button m:win32api.SendMessage(self.hwnd, win32con.WM_MBUTTONDOWN, win32con.MK_MBUTTON, point)time.sleep(interval)win32api.SendMessage(self.hwnd, win32con.WM_MBUTTONUP, win32con.MK_MBUTTON, point)elif button r:win32api.SendMessage(self.hwnd, win32con.WM_RBUTTONDOWN, win32con.MK_RBUTTON, point)time.sleep(interval)win32api.SendMessage(self.hwnd, win32con.WM_RBUTTONUP, win32con.MK_RBUTTON, point)print(clicked x: str(x) , y: str(y))# 模拟鼠标的左键双击def doubleClick(self, x, y):point win32api.MAKELONG(int(x), int(y))win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONDBLCLK, win32con.MK_LBUTTON, point)win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, point)print(doubleClick x: str(x) , y: str(y))# 模拟鼠标移动到坐标并进行左键单击def moveToPosClick(self, x, y):point win32api.MAKELONG(int(x), int(y))win32api.SendMessage(self.hwnd, win32con.WM_MOUSEMOVE, win32con.MK_LBUTTON, point)win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, point)win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, point)print(moveToPosClick x: str(x) , y: str(y))# 模拟鼠标移动到坐标并进行左键双击def moveToPosDoubleClick(self, x, y):point win32api.MAKELONG(int(x), int(y))win32api.SendMessage(self.hwnd, win32con.WM_MOUSEMOVE, win32con.MK_LBUTTON, point)win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONDBLCLK, win32con.MK_LBUTTON, point)win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, point)print(moveToPosDoubleClick x: str(x) , y: str(y))# 模拟鼠标使用滚轮向上滚动# 需要聚焦到窗口def wheelUp(self, x, y):self.focusHwnd()point win32api.MAKELONG(int(x), int(y))win32api.SendMessage(self.hwnd, win32con.WM_MOUSEWHEEL, win32con.WHEEL_DELTA * 5, point)print(wheelDown x: str(x) , y: str(y))# 模拟鼠标使用滚轮向下滚动# 需要聚焦到窗口def wheelDown(self, x, y):self.focusHwnd()point win32api.MAKELONG(int(x), int(y))win32api.SendMessage(self.hwnd, win32con.WM_MOUSEWHEEL, win32con.MK_LBUTTON, point)print(wheelDown x: str(x) , y: str(y))# 模拟鼠标的左键拖动(即在第一个点按下拖动至第二个点抬起)# step 步长模拟拖动会将一个操作分开多次来模拟次数拖动的长度/步长# delay 拖动时间默认0.5秒# isNeedBtnUp 是否需要弹起鼠标默认是若不弹起可通过多次调用实现轨迹拖动def slide(self, x1, y1, x2, y2, isNeedBtnUpTrue, step20, delay0.5):offsetX x2-x1offsetY y2-y1count int(math.sqrt(offsetX*offsetX offsetY*offsetY) / step)win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, win32api.MAKELONG(int(x1), int(y1)))for i in range(count):point2 win32api.MAKELONG(int(x1offsetX/count*(i1)), int(y1offsetY/count*(i1)))win32api.SendMessage(self.hwnd, win32con.WM_MOUSEMOVE, win32con.MK_LBUTTON, point2)time.sleep(delay/count)if isNeedBtnUp:win32api.SendMessage(self.hwnd, win32con.WM_LBUTTONUP, 0, point2)print(slide x1: str(x1) , y1: str(y1) , x2: str(x2) , y2: str(y2))这里同样使用win32api的SendMessage方法来实现鼠标的后台模拟此方法的原型在键盘模拟中提过了这里不再复述。
使用后台键盘模拟需要绑定窗口句柄关于窗口句柄的获取可以看看下面这篇文章Python自动化(1)——获取窗口句柄
完整自动化工程代码https://gitee.com/chj-self/PythonRobotization
大佬们找到问题欢迎拍砖~