Как в питоне имитировать нажатие на клавиатуре кнопок со стрелками
Пытаюсь сделать скрипт для автоматизации действий в компьютерной игре. Короче - скрипт должен жать кнопки вместо меня, в результате в игре (которую не я написал, я просто игрок) происходят некие действия.
Вот такой код:
import time
import keyboard
time.sleep(1)
keyboard.send('enter')
time.sleep(0.2)
keyboard.press('down')
time.sleep(0.2)
keyboard.release('down')
time.sleep(0.2)
keyboard.press('down')
time.sleep(0.2)
keyboard.release('down')
time.sleep(0.2)
работает некорректно. Игра воспринимает стрелки как стрелки, нажатые на цифровой клавиатуре. А нужны обычные стрелки.
Что можно сделать? Может быть стоит использовать другой модуль эмуляции клавиатуры?
Ответы (5 шт):
Как вариант, попробуйте использовать event
Если защита в игре так себе, то может и сработать...а может и не сработать.
import ctypes
import time
# Константы для keybd_event
VK_UP = 0x26 # Клавиша вверх
VK_DOWN = 0x28 # Клавиша вниз
# Эмуляция нажатия и отпускания клавиши вверх
ctypes.windll.user32.keybd_event(VK_UP, 0, 0, 0)
time.sleep(0.1)
ctypes.windll.user32.keybd_event(VK_UP, 0, 2, 0)
time.sleep(0.1)
# Эмуляция нажатия и отпускания клавиши вниз
ctypes.windll.user32.keybd_event(VK_DOWN, 0, 0, 0)
time.sleep(0.1)
ctypes.windll.user32.keybd_event(VK_DOWN, 0, 2, 0)
Для других клавиш используйте соответствующие коды: https://narvell.nl/keys
Можно попробовать использовать SendInput, для этих целей у меня есть вот такой класс:
import ctypes
import time
class InputSimulator:
def __init__(self):
# Константы для ввода мыши
self.WHEEL_DELTA = 120
self.XBUTTON1 = 0x0001
self.XBUTTON2 = 0x0002
self.MOUSEEVENTF_ABSOLUTE = 0x8000
self.MOUSEEVENTF_HWHEEL = 0x01000
self.MOUSEEVENTF_MOVE = 0x0001
self.MOUSEEVENTF_MOVE_NOCOALESCE = 0x2000
self.MOUSEEVENTF_LEFTDOWN = 0x0002
self.MOUSEEVENTF_LEFTUP = 0x0004
self.MOUSEEVENTF_RIGHTDOWN = 0x0008
self.MOUSEEVENTF_RIGHTUP = 0x0010
self.MOUSEEVENTF_MIDDLEDOWN = 0x0020
self.MOUSEEVENTF_MIDDLEUP = 0x0040
self.MOUSEEVENTF_VIRTUALDESK = 0x4000
self.MOUSEEVENTF_WHEEL = 0x0800
self.MOUSEEVENTF_XDOWN = 0x0080
self.MOUSEEVENTF_XUP = 0x0100
# Константы для типов ввода
self.INPUT_MOUSE = 0
self.INPUT_KEYBOARD = 1
self.INPUT_HARDWARE = 2
# Коды клавиш
self.VK_LBUTTON = 0x01 # Left mouse button
self.VK_RBUTTON = 0x02 # Right mouse button
self.VK_CANCEL = 0x03 # Control-break processing
self.VK_MBUTTON = 0x04 # Middle mouse button (three-button mouse)
self.VK_XBUTTON1 = 0x05 # X1 mouse button
self.VK_XBUTTON2 = 0x06 # X2 mouse button
self.VK_BACK = 0x08 # BACKSPACE key
self.VK_TAB = 0x09 # TAB key
self.VK_CLEAR = 0x0C # CLEAR key
self.VK_RETURN = 0x0D # ENTER key
self.VK_SHIFT = 0x10 # SHIFT key
self.VK_CONTROL = 0x11 # CTRL key
self.VK_MENU = 0x12 # ALT key
self.VK_PAUSE = 0x13 # PAUSE key
self.VK_CAPITAL = 0x14 # CAPS LOCK key
self.VK_KANA = 0x15 # IME Kana mode
self.VK_HANGUL = 0x15 # IME Hangul mode
self.VK_JUNJA = 0x17 # IME Junja mode
self.VK_FINAL = 0x18 # IME final mode
self.VK_HANJA = 0x19 # IME Hanja mode
self.VK_KANJI = 0x19 # IME Kanji mode
self.VK_ESCAPE = 0x1B # ESC key
self.VK_CONVERT = 0x1C # IME convert
self.VK_NONCONVERT = 0x1D # IME nonconvert
self.VK_ACCEPT = 0x1E # IME accept
self.VK_MODECHANGE = 0x1F # IME mode change request
self.VK_SPACE = 0x20 # SPACEBAR
self.VK_PRIOR = 0x21 # PAGE UP key
self.VK_NEXT = 0x22 # PAGE DOWN key
self.VK_END = 0x23 # END key
self.VK_HOME = 0x24 # HOME key
self.VK_LEFT = 0x25 # LEFT ARROW key
self.VK_UP = 0x26 # UP ARROW key
self.VK_RIGHT = 0x27 # RIGHT ARROW key
self.VK_DOWN = 0x28 # DOWN ARROW key
self.VK_SELECT = 0x29 # SELECT key
self.VK_PRINT = 0x2A # PRINT key
self.VK_EXECUTE = 0x2B # EXECUTE key
self.VK_SNAPSHOT = 0x2C # PRINT SCREEN key
self.VK_INSERT = 0x2D # INS key
self.VK_DELETE = 0x2E # DEL key
self.VK_HELP = 0x2F # HELP key
self.VK_LWIN = 0x5B # Left Windows key (Natural keyboard)
self.VK_RWIN = 0x5C # Right Windows key (Natural keyboard)
self.VK_APPS = 0x5D # Applications key (Natural keyboard)
self.VK_SLEEP = 0x5F # Computer Sleep key
self.VK_NUMPAD0 = 0x60 # Numeric keypad 0 key
self.VK_NUMPAD1 = 0x61 # Numeric keypad 1 key
self.VK_NUMPAD2 = 0x62 # Numeric keypad 2 key
self.VK_NUMPAD3 = 0x63 # Numeric keypad 3 key
self.VK_NUMPAD4 = 0x64 # Numeric keypad 4 key
self.VK_NUMPAD5 = 0x65 # Numeric keypad 5 key
self.VK_NUMPAD6 = 0x66 # Numeric keypad 6 key
self.VK_NUMPAD7 = 0x67 # Numeric keypad 7 key
self.VK_NUMPAD8 = 0x68 # Numeric keypad 8 key
self.VK_NUMPAD9 = 0x69 # Numeric keypad 9 key
self.VK_MULTIPLY = 0x6A # Multiply key
self.VK_ADD = 0x6B # Add key
self.VK_SEPARATOR = 0x6C # Separator key
self.VK_SUBTRACT = 0x6D # Subtract key
self.VK_DECIMAL = 0x6E # Decimal key
self.VK_DIVIDE = 0x6F # Divide key
self.VK_F1 = 0x70 # F1 key
self.VK_F2 = 0x71 # F2 key
self.VK_F3 = 0x72 # F3 key
self.VK_F4 = 0x73 # F4 key
self.VK_F5 = 0x74 # F5 key
self.VK_F6 = 0x75 # F6 key
self.VK_F7 = 0x76 # F7 key
self.VK_F8 = 0x77 # F8 key
self.VK_F9 = 0x78 # F9 key
self.VK_F10 = 0x79 # F10 key
self.VK_F11 = 0x7A # F11 key
self.VK_F12 = 0x7B # F12 key
self.VK_F13 = 0x7C # F13 key
self.VK_F14 = 0x7D # F14 key
self.VK_F15 = 0x7E # F15 key
self.VK_F16 = 0x7F # F16 key
self.VK_F17 = 0x80 # F17 key
self.VK_F18 = 0x81 # F18 key
self.VK_F19 = 0x82 # F19 key
self.VK_F20 = 0x83 # F20 key
self.VK_F21 = 0x84 # F21 key
self.VK_F22 = 0x85 # F22 key
self.VK_F23 = 0x86 # F23 key
self.VK_F24 = 0x87 # F24 key
self.VK_NUMLOCK = 0x90 # NUM LOCK key
self.VK_SCROLL = 0x91 # SCROLL LOCK key
self.VK_LSHIFT = 0xA0 # Left SHIFT key
self.VK_RSHIFT = 0xA1 # Right SHIFT key
self.VK_LCONTROL = 0xA2 # Left CONTROL key
self.VK_RCONTROL = 0xA3 # Right CONTROL key
self.VK_LMENU = 0xA4 # Left MENU key
self.VK_RMENU = 0xA5 # Right MENU key
self.VK_BROWSER_BACK = 0xA6 # Browser Back key
self.VK_BROWSER_FORWARD = 0xA7 # Browser Forward key
self.VK_BROWSER_REFRESH = 0xA8 # Browser Refresh key
self.VK_BROWSER_STOP = 0xA9 # Browser Stop key
self.VK_BROWSER_SEARCH = 0xAA # Browser Search key
self.VK_BROWSER_FAVORITES = 0xAB # Browser Favorites key
self.VK_BROWSER_HOME = 0xAC # Browser Start and Home key
self.VK_VOLUME_MUTE = 0xAD # Volume Mute key
self.VK_VOLUME_DOWN = 0xAE # Volume Down key
self.VK_VOLUME_UP = 0xAF # Volume Up key
self.VK_MEDIA_NEXT_TRACK = 0xB0 # Next Track key
self.VK_MEDIA_PREV_TRACK = 0xB1 # Previous Track key
self.VK_MEDIA_STOP = 0xB2 # Stop Media key
self.VK_MEDIA_PLAY_PAUSE = 0xB3 # Play/Pause Media key
self.VK_LAUNCH_MAIL = 0xB4 # Start Mail key
self.VK_LAUNCH_MEDIA_SELECT = 0xB5 # Select Media key
self.VK_LAUNCH_APP1 = 0xB6 # Start Application 1 key
self.VK_LAUNCH_APP2 = 0xB7 # Start Application 2 key
self.VK_OEM_1 = 0xBA # Used for miscellaneous characters; it can vary by keyboard.
# For the US standard keyboard, the ';:' key
self.VK_OEM_PLUS = 0xBB # For any country/region, the '+' key
self.VK_OEM_COMMA = 0xBC # For any country/region, the ',' key
self.VK_OEM_MINUS = 0xBD # For any country/region, the '-' key
self.VK_OEM_PERIOD = 0xBE # For any country/region, the '.' key
self.VK_OEM_2 = 0xBF # Used for miscellaneous characters; it can vary by keyboard.
# For the US standard keyboard, the '/?' key
self.VK_OEM_3 = 0xC0 # Used for miscellaneous characters; it can vary by keyboard.
# For the US standard keyboard, the '`~' key
self.VK_OEM_4 = 0xDB # Used for miscellaneous characters; it can vary by keyboard.
# For the US standard keyboard, the '[{' key
self.VK_OEM_5 = 0xDC # Used for miscellaneous characters; it can vary by keyboard.
# For the US standard keyboard, the '\|' key
self.VK_OEM_6 = 0xDD # Used for miscellaneous characters; it can vary by keyboard.
# For the US standard keyboard, the ']}' key
self.VK_OEM_7 = 0xDE # Used for miscellaneous characters; it can vary by keyboard.
# For the US standard keyboard, the 'single-quote/double-quote' key
self.VK_OEM_8 = 0xDF # Used for miscellaneous characters; it can vary by keyboard.
self.VK_OEM_102 = 0xE2 # Either the angle bracket key or the backslash key on the RT 102-key keyboard
self.VK_PROCESSKEY = 0xE5 # IME PROCESS key
self.VK_PACKET = 0xE7 # Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP
self.VK_ATTN = 0xF6 # Attn key
self.VK_CRSEL = 0xF7 # CrSel key
self.VK_EXSEL = 0xF8 # ExSel key
self.VK_EREOF = 0xF9 # Erase EOF key
self.VK_PLAY = 0xFA # Play key
self.VK_ZOOM = 0xFB # Zoom key
self.VK_PA1 = 0xFD # PA1 key
self.VK_OEM_CLEAR = 0xFE # Clear key
# Константы для ввода клавиатуры
self.KEYEVENTF_EXTENDEDKEY = 0x0001
self.KEYEVENTF_KEYUP = 0x0002
self.KEYEVENTF_SCANCODE = 0x0008
self.KEYEVENTF_UNICODE = 0x0004
self.KEY_0 = 0x30
self.KEY_1 = 0x31
self.KEY_2 = 0x32
self.KEY_3 = 0x33
self.KEY_4 = 0x34
self.KEY_5 = 0x35
self.KEY_6 = 0x36
self.KEY_7 = 0x37
self.KEY_8 = 0x38
self.KEY_9 = 0x39
self.KEY_A = 0x41
self.KEY_B = 0x42
self.KEY_C = 0x43
self.KEY_D = 0x44
self.KEY_E = 0x45
self.KEY_F = 0x46
self.KEY_G = 0x47
self.KEY_H = 0x48
self.KEY_I = 0x49
self.KEY_J = 0x4A
self.KEY_K = 0x4B
self.KEY_L = 0x4C
self.KEY_M = 0x4D
self.KEY_N = 0x4E
self.KEY_O = 0x4F
self.KEY_P = 0x50
self.KEY_Q = 0x51
self.KEY_R = 0x52
self.KEY_S = 0x53
self.KEY_T = 0x54
self.KEY_U = 0x55
self.KEY_V = 0x56
self.KEY_W = 0x57
self.KEY_X = 0x58
self.KEY_Y = 0x59
self.KEY_Z = 0x5A
# Объявление структур
class MOUSEINPUT(ctypes.Structure):
_fields_ = [
('dx', ctypes.c_long),
('dy', ctypes.c_long),
('mouseData', ctypes.c_ulong),
('dwFlags', ctypes.c_ulong),
('time', ctypes.c_ulong),
('dwExtraInfo', ctypes.POINTER(ctypes.c_ulong))
]
class KEYBDINPUT(ctypes.Structure):
_fields_ = [
('wVk', ctypes.c_ushort),
('wScan', ctypes.c_ushort),
('dwFlags', ctypes.c_ulong),
('time', ctypes.c_ulong),
('dwExtraInfo', ctypes.POINTER(ctypes.c_ulong))
]
class HARDWAREINPUT(ctypes.Structure):
_fields_ = [
('uMsg', ctypes.c_ulong),
('wParamL', ctypes.c_ushort),
('wParamH', ctypes.c_ushort)
]
class _INPUTunion(ctypes.Union):
_fields_ = [
('mi', MOUSEINPUT),
('ki', KEYBDINPUT),
('hi', HARDWAREINPUT)
]
class INPUT(ctypes.Structure):
_fields_ = [
('type', ctypes.c_ulong),
('union', _INPUTunion)
]
self.MOUSEINPUT = MOUSEINPUT
self.KEYBDINPUT = KEYBDINPUT
self.HARDWAREINPUT = HARDWAREINPUT
self._INPUTunion = _INPUTunion
self.INPUT = INPUT
def SendInput(self, *inputs):
nInputs = len(inputs)
LPINPUT = self.INPUT * nInputs
pInputs = LPINPUT(*inputs)
cbSize = ctypes.c_int(ctypes.sizeof(inputs[0]))
return ctypes.windll.user32.SendInput(nInputs, pInputs, cbSize)
def MouseInput(self, flags, x, y, data):
return self.MOUSEINPUT(x, y, data, flags, 0, None)
def KeybdInput(self, code, flags):
return self.KEYBDINPUT(code, code, flags, 0, None)
def HardwareInput(self, message, parameter):
return self.HARDWAREINPUT(message & 0xFFFFFFFF, parameter & 0xFFFF, parameter >> 16 & 0xFFFF)
def Mouse(self, flags, x=0, y=0, data=0):
return self.INPUT(self.INPUT_MOUSE, self._INPUTunion(mi=self.MouseInput(flags, x, y, data)))
def Keyboard(self, code, flags=0):
return self.INPUT(self.INPUT_KEYBOARD, self._INPUTunion(ki=self.KeybdInput(code, flags)))
def Hardware(self, message, parameter=0):
return self.INPUT(self.INPUT_HARDWARE, self._INPUTunion(hi=self.HardwareInput(message, parameter)))
input_simulator = InputSimulator()
# Ожидание некоторого времени перед выполнением симуляции, чтобы у вас было время подвести мышь
time.sleep(5)
# Симуляция нажатия левой кнопки мыши
input_simulator.SendInput(input_simulator.Mouse(input_simulator.MOUSEEVENTF_LEFTDOWN))
# Ожидание перед отпусканием кнопки мыши
time.sleep(0.1)
# Симуляция отпускания левой кнопки мыши
input_simulator.SendInput(input_simulator.Mouse(input_simulator.MOUSEEVENTF_LEFTUP))
time.sleep(0.1)
# Симуляция нажатия левой кнопки мыши
input_simulator.SendInput(input_simulator.Mouse(input_simulator.MOUSEEVENTF_LEFTDOWN))
# Ожидание перед отпусканием кнопки мыши
time.sleep(0.1)
# Симуляция отпускания левой кнопки мыши
input_simulator.SendInput(input_simulator.Mouse(input_simulator.MOUSEEVENTF_LEFTUP))
# Ожидание перед симуляцией движения мыши (абсолютное)
time.sleep(0.1)
# Симуляция абсолютного движения мыши в точку (500, 500)
input_simulator.SendInput(input_simulator.Mouse(input_simulator.MOUSEEVENTF_MOVE | input_simulator.MOUSEEVENTF_ABSOLUTE, 500, 500, 0))
# Ожидание перед симуляцией относительного движения мыши
time.sleep(0.1)
# Симуляция относительного движения мыши на 50 пикселей вправо и 50 пикселей вниз от текущей позиции
input_simulator.SendInput(input_simulator.Mouse(input_simulator.MOUSEEVENTF_MOVE, 50, 50, 0))
# Ожидание перед симуляцией нажатия клавиши вверх
time.sleep(0.1)
# Симуляция нажатия клавиши вверх
input_simulator.SendInput(input_simulator.Keyboard(input_simulator.VK_UP))
# Ожидание перед отпусканием клавиши вверх
time.sleep(0.1)
# Симуляция отпускания клавиши вверх
input_simulator.SendInput(input_simulator.Keyboard(input_simulator.VK_UP, input_simulator.KEYEVENTF_KEYUP))
# Ожидание перед симуляцией нажатия клавиши вниз
time.sleep(0.1)
# Симуляция нажатия клавиши вниз
input_simulator.SendInput(input_simulator.Keyboard(input_simulator.VK_DOWN))
# Ожидание перед отпусканием клавиши вниз
time.sleep(0.1)
# Симуляция отпускания клавиши вниз
input_simulator.SendInput(input_simulator.Keyboard(input_simulator.VK_DOWN, input_simulator.KEYEVENTF_KEYUP))
Есть интересный проект AutoHotkey
Для версии 1.1 есть библиотека на питоне pip install ahk
Вот вам небольшой пример как можно с ней работать:
import ahk
# Скрипт AutoHotKey в переменной
ahk_script = """
Menu, Tray, NoIcon ;
#Persistent ; Скрипт остается активным
; Ждем 5 секунд
Sleep, 5000
Send, {F1 down}
Sleep, 2000 ; Удерживаем 'F1' в течение 2 секунд
Send, {F1 up}
; Завершаем скрипт
ExitApp
"""
# Запустите скрипт AutoHotKey
ahk.run_script(ahk_script)
Последний вариант - это использовать дескриптор окна и посылать команды непосредственно в него:
pip install pywin32
import win32gui
import win32api
import win32con
set_hwnd = "Notepad"
hwnd = win32gui.FindWindow(None, set_hwnd)
if hwnd == 0:
print("Окно не найдено!\n")
lParam = win32api.MAKELONG(0, 0)
win32api.PostMessage(hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, lParam)
win32api.PostMessage(hwnd, win32con.WM_LBUTTONUP, 0, lParam)
Вместо PostMessage можно использовать SendMessage.
win32api.SendMessage(hwnd, win32con.WM_MOUSEMOVE, 0, lParam)
Разница между ними в том, что SendMessage отправляет сообщение и ожидает, пока окно-получатель сообщение обработает, а PostMessage просто установит сообщение в очередь.
Примерно так же, можно отправлять нажатия клавиш клавиатуры.
Самым крайним решением можно считать usb-устройство, которое можно запрограммировать на подачу нужного сигнала — Digispark.
pip install digispark
Цена вопроса: ~500р
