Python實(shí)現(xiàn)Windows鍵盤鼠標(biāo)自動化模擬器
本文介紹一個(gè)基于Python的Windows鍵盤鼠標(biāo)自動化模擬器,適合自動化測試、游戲輔助等場景。代碼通過ctypes調(diào)用Windows API實(shí)現(xiàn)底層輸入模擬。
實(shí)測案例:bongo cat刷點(diǎn)擊

1. 主要功能
模擬鍵盤按鍵(按下、釋放、完整按鍵)
模擬鼠標(biāo)點(diǎn)擊(左鍵、右鍵,可指定坐標(biāo))
支持絕對坐標(biāo)定位
可自定義點(diǎn)擊間隔和范圍
2. 代碼結(jié)構(gòu)
2.1 InputSimulator類
負(fù)責(zé)封裝所有輸入模擬相關(guān)方法。
class InputSimulator:
def __init__(self):
self.user32 = ctypes.WinDLL('user32', use_last_error=True)
# ... 定義各種常量 ...
主要方法
press_key(key_code):模擬按鍵按下release_key(key_code):模擬按鍵釋放key_press(key_code, duration=0.1):完整按鍵(按下+延時(shí)+釋放)click_mouse(x=None, y=None):模擬鼠標(biāo)左鍵點(diǎn)擊(可指定坐標(biāo))right_click_mouse(x=None, y=None):模擬鼠標(biāo)右鍵點(diǎn)擊(可指定坐標(biāo))
2.2 結(jié)構(gòu)體定義
使用ctypes定義Windows API所需的結(jié)構(gòu)體:
class MOUSEINPUT(ctypes.Structure):
_fields_ = (
("dx", wintypes.LONG),
("dy", wintypes.LONG),
("mouseData", wintypes.DWORD),
("dwFlags", wintypes.DWORD),
("time", wintypes.DWORD),
("dwExtraInfo", ctypes.POINTER(wintypes.ULONG))
)
# 還有 KEYBDINPUT 和 INPUT 結(jié)構(gòu)體
2.3 示例用法
主程序部分演示了如何自動點(diǎn)擊:
if __name__ == "__main__":
import keyboard
import random
simulator = InputSimulator()
print("程序已啟動,按Q鍵退出...")
while True:
if keyboard.is_pressed('q'):
print("檢測到Q鍵,程序退出")
break
x = random.randint(1000, 1100)
y = random.randint(700, 800)
simulator.click_mouse(x, y)
time.sleep(random.uniform(0.05, 0.1))
- 隨機(jī)生成點(diǎn)擊坐標(biāo)
- 按Q鍵可隨時(shí)退出
3. 技術(shù)要點(diǎn)
ctypes調(diào)用user32.dll:實(shí)現(xiàn)底層輸入模擬
支持絕對坐標(biāo):通過65535縮放映射屏幕坐標(biāo)
結(jié)構(gòu)體封裝:與Windows API參數(shù)完全兼容
可擴(kuò)展性強(qiáng):可根據(jù)需要添加更多輸入事件
4. 注意事項(xiàng)
僅支持Windows系統(tǒng)
需管理員權(quán)限
請勿在重要操作界面誤用
5. 應(yīng)用場景
- 自動化測試
- 游戲腳本
- 重復(fù)性辦公自動化
- 系統(tǒng)集成測試
完整代碼見下方:
import ctypes
import time
from ctypes import wintypes
class InputSimulator:
def __init__(self):
self.user32 = ctypes.WinDLL('user32', use_last_error=True)
# Windows API 常量
self.INPUT_MOUSE = 0
self.INPUT_KEYBOARD = 1
self.KEYEVENTF_KEYUP = 0x0002
self.KEYEVENTF_UNICODE = 0x0004
self.MOUSEEVENTF_LEFTDOWN = 0x0002
self.MOUSEEVENTF_LEFTUP = 0x0004
self.MOUSEEVENTF_RIGHTDOWN = 0x0008
self.MOUSEEVENTF_RIGHTUP = 0x0010
self.MOUSEEVENTF_MOVE = 0x0001
self.MOUSEEVENTF_ABSOLUTE = 0x8000
def press_key(self, key_code):
"""模擬按鍵按下"""
x = INPUT(type=self.INPUT_KEYBOARD,
ki=KEYBDINPUT(wVk=key_code))
self.user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))
def release_key(self, key_code):
"""模擬按鍵釋放"""
x = INPUT(type=self.INPUT_KEYBOARD,
ki=KEYBDINPUT(wVk=key_code,
dwFlags=self.KEYEVENTF_KEYUP))
self.user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))
def key_press(self, key_code, duration=0.1):
"""模擬完整的按鍵過程"""
self.press_key(key_code)
time.sleep(duration)
self.release_key(key_code)
def click_mouse(self, x=None, y=None):
"""模擬鼠標(biāo)點(diǎn)擊
參數(shù):
x: 鼠標(biāo)x坐標(biāo)(可選)
y: 鼠標(biāo)y坐標(biāo)(可選)
"""
if x is not None and y is not None:
screen_width = self.user32.GetSystemMetrics(0)
screen_height = self.user32.GetSystemMetrics(1)
x = int(x * 65535 / screen_width)
y = int(y * 65535 / screen_height)
move = INPUT(type=self.INPUT_MOUSE,
mi=MOUSEINPUT(dx=x, dy=y,
dwFlags=self.MOUSEEVENTF_MOVE | self.MOUSEEVENTF_ABSOLUTE))
self.user32.SendInput(1, ctypes.byref(move), ctypes.sizeof(move))
time.sleep(0.1)
down = INPUT(type=self.INPUT_MOUSE,
mi=MOUSEINPUT(dwFlags=self.MOUSEEVENTF_LEFTDOWN))
self.user32.SendInput(1, ctypes.byref(down), ctypes.sizeof(down))
time.sleep(0.1)
up = INPUT(type=self.INPUT_MOUSE,
mi=MOUSEINPUT(dwFlags=self.MOUSEEVENTF_LEFTUP))
self.user32.SendInput(1, ctypes.byref(up), ctypes.sizeof(up))
def right_click_mouse(self, x=None, y=None):
"""模擬鼠標(biāo)右鍵點(diǎn)擊"""
if x is not None and y is not None:
screen_width = self.user32.GetSystemMetrics(0)
screen_height = self.user32.GetSystemMetrics(1)
x = int(x * 65535 / screen_width)
y = int(y * 65535 / screen_height)
move = INPUT(type=self.INPUT_MOUSE,
mi=MOUSEINPUT(dx=x, dy=y,
dwFlags=self.MOUSEEVENTF_MOVE | self.MOUSEEVENTF_ABSOLUTE))
self.user32.SendInput(1, ctypes.byref(move), ctypes.sizeof(move))
time.sleep(0.1)
down = INPUT(type=self.INPUT_MOUSE,
mi=MOUSEINPUT(dwFlags=self.MOUSEEVENTF_RIGHTDOWN))
self.user32.SendInput(1, ctypes.byref(down), ctypes.sizeof(down))
time.sleep(0.1)
up = INPUT(type=self.INPUT_MOUSE,
mi=MOUSEINPUT(dwFlags=self.MOUSEEVENTF_RIGHTUP))
self.user32.SendInput(1, ctypes.byref(up), ctypes.sizeof(up))
# 保持原有的結(jié)構(gòu)體定義
class MOUSEINPUT(ctypes.Structure):
_fields_ = (
("dx", wintypes.LONG),
("dy", wintypes.LONG),
("mouseData", wintypes.DWORD),
("dwFlags", wintypes.DWORD),
("time", wintypes.DWORD),
("dwExtraInfo", ctypes.POINTER(wintypes.ULONG))
)
class KEYBDINPUT(ctypes.Structure):
_fields_ = (
("wVk", wintypes.WORD),
("wScan", wintypes.WORD),
("dwFlags", wintypes.DWORD),
("time", wintypes.DWORD),
("dwExtraInfo", ctypes.POINTER(wintypes.ULONG))
)
class INPUT(ctypes.Structure):
class _INPUT(ctypes.Union):
_fields_ = (
("mi", MOUSEINPUT),
("ki", KEYBDINPUT)
)
_anonymous_ = ("_input",)
_fields_ = (
("type", wintypes.DWORD),
("_input", _INPUT)
)
# 使用示例
if __name__ == "__main__":
"""
# 創(chuàng)建模擬器實(shí)例
simulator = InputSimulator()
# 示例:模擬按下A鍵
simulator.key_press(0x41)
# 示例:模擬鼠標(biāo)點(diǎn)擊
simulator.click_mouse()
# 示例:在指定位置右鍵點(diǎn)擊
simulator.right_click_mouse(100, 100)
"""
import keyboard
import random
simulator = InputSimulator()
print("程序已啟動,按Q鍵退出...")
while True:
if keyboard.is_pressed('q'):
print("檢測到Q鍵,程序退出")
break
# 隨機(jī)坐標(biāo)(在1000-1100和700-800范圍內(nèi))
x = random.randint(1000, 1100)
y = random.randint(700, 800)
# # 模擬鼠標(biāo)右鍵點(diǎn)擊
# simulator.right_click_mouse(x, y)
# time.sleep(random.uniform(0.05, 0.1))
# 模擬鼠標(biāo)左鍵點(diǎn)擊
simulator.click_mouse(x, y)
time.sleep(random.uniform(0.05, 0.1))
到此這篇關(guān)于Python實(shí)現(xiàn)Windows鍵盤鼠標(biāo)自動化模擬器的文章就介紹到這了,更多相關(guān)Python模擬鍵盤鼠標(biāo)操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Pandas?合并數(shù)據(jù)集merge?和?join的使用
Pandas?提供了一個(gè)重要的功能,即高性能的內(nèi)存中連接(join)和合并(merge)操作,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2026-06-06
一行Python代碼過濾標(biāo)點(diǎn)符號等特殊字符
這篇文章主要介紹了一行Python代碼過濾標(biāo)點(diǎn)符號等特殊字符的相關(guān)知識,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08
Django學(xué)習(xí)筆記之ORM基礎(chǔ)教程
ORM,即Object-Relational Mapping(對象關(guān)系映射),它的作用是在關(guān)系型數(shù)據(jù)庫和業(yè)務(wù)實(shí)體對象之間作一個(gè)映射,下面這篇文章主要給大家介紹了關(guān)于Django學(xué)習(xí)筆記之ORM基礎(chǔ)教程的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。2018-03-03
python 文件的基本操作 菜中菜功能的實(shí)例代碼
這篇文章主要介紹了python 文件的基本操作 菜中菜功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-07-07
Python數(shù)據(jù)結(jié)構(gòu)與算法中的棧詳解(3)
這篇文章主要為大家詳細(xì)介紹了Python中的棧,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03
使用Python實(shí)現(xiàn)從麥克風(fēng)獲取音頻并識別
這篇文章主要為大家詳細(xì)介紹了如何使用Python實(shí)現(xiàn)從麥克風(fēng)獲取音頻并識別功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-02-02

