Python에서 키보드 이벤트를 생성하는 방법은 무엇입니까?


99

짧은 요약:

모든 목적을 위해 시뮬레이션 된 이벤트를 키보드의 실제 키 입력으로 처리해야하는 컴퓨터에 키보드 이벤트를 보내는 프로그램을 만들려고합니다.

원래 게시물 :

파이썬을 사용하여 키보드 이벤트를 생성하는 방법을 찾고 있습니다.

함수가 다음과 같이 누르기를 시뮬레이트해야하는 키를 수신한다고 가정합니다.

keyboardevent('a') #lower case 'a'
keyboardevent('B') #upper case 'B'
keyboardevent('->') # right arrow key

def keyboardevent(key):
    #code that simulated 'key' being pressed on keyboard

위는 당연히 예시이지만 내가 찾고있는 것은 키보드 이벤트를 시뮬레이션하는 데 사용할 수있는 라이브러리, 모듈 또는 기타입니다.

참고 : 이것은 메모장에 문자를 보내거나 필드 등에 텍스트를 입력하는 것과 다릅니다. 파이썬 스크립트가 실제 키보드 이벤트를 시뮬레이션하기를 원합니다. 컴퓨터는 실제로 키보드 이벤트가 있다고 생각할 것입니다.

추가 참고 :

활성 창에 키 입력을 보내고 싶지 않습니다. 일부 활성 창에서 특정 키 조합을 허용하지 않거나 키보드 단축키를 사용하려는 경우 시스템이 키보드의 키가 눌려 있다고 믿기를 원합니다. 내 스크립트를 통한 백그라운드 프로세스의 경우 활성 창을 통과 할 필요가 없습니다.

지금까지 나는 다음 사항을 살펴 보았습니다.

최전방 애플리케이션에 대한 키보드 이벤트 생성

Python을 통해 키보드 키 누르기 이벤트를 생성하는 방법은 무엇입니까?

그것은 모두 사과에 관한 것이었고 전혀 도움이되지 않았습니다.

이:

Python에서 키보드와 마우스를 시뮬레이션하는 가장 쉬운 방법은 무엇입니까?

필요한 것 같지만 라이브러리 또는 문서를 찾을 수 없습니다.

나는 더 많은 장소를 검색했지만 아직 해결책을 찾지 못했습니다.


3
내가 아는 유일한 것은 Windows 전용 인 SendKeys 입니다. 이것은 크로스 플랫폼 솔루션이없는 문제인 것 같습니다. 왜 이것이 필요합니까? 어떤 문제를 해결하고 있습니까?
Steven Rumbalski

들어 X플랫폼이 xdotool있지만, 일반적으로 기본적으로 설치되지 않습니다. 나는 X당신이 원하는 것을 수행하는 최소한의 모듈을 C로 작성하기 위해 문서를 읽는 것이 어렵지 않을 것이라고 믿습니다 (나는 xsendkeys얼마 전에 프로그램 이 있었다고 생각합니다 ).
Bakuriu 2012

@StevenRumbalski 감사합니다, 이것은 유망 해 보이지만 추가하고 싶습니다. 제 질문을 편집하겠습니다. 활성 창에 키 입력을 보내고 싶지 않습니다. 일부 활성 창이 특정 키 조합을 허용하지 않거나 백그라운드 프로세스에 키보드 바로 가기를 사용하려는 경우 시스템이 키보드 키가 눌리고 있다는 미묘한 차이를 믿기를 원합니다. 내 스크립트를 통해 활성 창을 통과 할 필요가 없습니다.
Inbar Rose 2011

3
순수한 파이썬이어야합니까? 크로스 플랫폼이어야합니까?
zenpoy

@zenpoy는 현재 Windows XP에서 작동하는 한 크로스 플랫폼 일 필요가 없으며, 적어도 파이썬은 7에서 작동합니다. 코드는 파이썬으로 작성 될 것입니다. 모듈 / 라이브러리 / 패키지 / dll이 파이썬에서 효과적으로 인터페이스 될 수 있다면 상관 없습니다. 이상적으로는 순수한 파이썬과 크로스 플랫폼이 될 것입니다.
Inbar Rose 2011

답변:


116

ctypes를 사용하여 수행 할 수 있습니다.

import ctypes
from ctypes import wintypes
import time

user32 = ctypes.WinDLL('user32', use_last_error=True)

INPUT_MOUSE    = 0
INPUT_KEYBOARD = 1
INPUT_HARDWARE = 2

KEYEVENTF_EXTENDEDKEY = 0x0001
KEYEVENTF_KEYUP       = 0x0002
KEYEVENTF_UNICODE     = 0x0004
KEYEVENTF_SCANCODE    = 0x0008

MAPVK_VK_TO_VSC = 0

# msdn.microsoft.com/en-us/library/dd375731
VK_TAB  = 0x09
VK_MENU = 0x12

# C struct definitions

wintypes.ULONG_PTR = wintypes.WPARAM

class MOUSEINPUT(ctypes.Structure):
    _fields_ = (("dx",          wintypes.LONG),
                ("dy",          wintypes.LONG),
                ("mouseData",   wintypes.DWORD),
                ("dwFlags",     wintypes.DWORD),
                ("time",        wintypes.DWORD),
                ("dwExtraInfo", wintypes.ULONG_PTR))

class KEYBDINPUT(ctypes.Structure):
    _fields_ = (("wVk",         wintypes.WORD),
                ("wScan",       wintypes.WORD),
                ("dwFlags",     wintypes.DWORD),
                ("time",        wintypes.DWORD),
                ("dwExtraInfo", wintypes.ULONG_PTR))

    def __init__(self, *args, **kwds):
        super(KEYBDINPUT, self).__init__(*args, **kwds)
        # some programs use the scan code even if KEYEVENTF_SCANCODE
        # isn't set in dwFflags, so attempt to map the correct code.
        if not self.dwFlags & KEYEVENTF_UNICODE:
            self.wScan = user32.MapVirtualKeyExW(self.wVk,
                                                 MAPVK_VK_TO_VSC, 0)

class HARDWAREINPUT(ctypes.Structure):
    _fields_ = (("uMsg",    wintypes.DWORD),
                ("wParamL", wintypes.WORD),
                ("wParamH", wintypes.WORD))

class INPUT(ctypes.Structure):
    class _INPUT(ctypes.Union):
        _fields_ = (("ki", KEYBDINPUT),
                    ("mi", MOUSEINPUT),
                    ("hi", HARDWAREINPUT))
    _anonymous_ = ("_input",)
    _fields_ = (("type",   wintypes.DWORD),
                ("_input", _INPUT))

LPINPUT = ctypes.POINTER(INPUT)

def _check_count(result, func, args):
    if result == 0:
        raise ctypes.WinError(ctypes.get_last_error())
    return args

user32.SendInput.errcheck = _check_count
user32.SendInput.argtypes = (wintypes.UINT, # nInputs
                             LPINPUT,       # pInputs
                             ctypes.c_int)  # cbSize

# Functions

def PressKey(hexKeyCode):
    x = INPUT(type=INPUT_KEYBOARD,
              ki=KEYBDINPUT(wVk=hexKeyCode))
    user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))

def ReleaseKey(hexKeyCode):
    x = INPUT(type=INPUT_KEYBOARD,
              ki=KEYBDINPUT(wVk=hexKeyCode,
                            dwFlags=KEYEVENTF_KEYUP))
    user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))

def AltTab():
    """Press Alt+Tab and hold Alt key for 2 seconds
    in order to see the overlay.
    """
    PressKey(VK_MENU)   # Alt
    PressKey(VK_TAB)    # Tab
    ReleaseKey(VK_TAB)  # Tab~
    time.sleep(2)
    ReleaseKey(VK_MENU) # Alt~

if __name__ == "__main__":
    AltTab()

hexKeyCodeWindows API에서 정의한 가상 키보드 매핑입니다. 코드 목록은 MSDN에서 사용할 수 있습니다. 가상 키 코드 (Windows)


지금까지이 아이디어가 마음에 듭니다. VK_Key의 목록을 찾을 수 없으며 예제 함수 호출을 올릴 수 있습니다.
Inbar Rose 2012

3
alt-tab을 누르는 간단한 방법을 추가합니다.
lucasg nov.

나는 이것을 훌륭하게 사용하고 있지만 이제 작은 문제가 있습니다. 당신이 나를 도울 수 있기를 바랍니다. 마우스 X, Y를 어떻게 움직일 수 있습니까?
Inbar Rose

15
중복 질문에 다음 시점 대신 대답을 복제의 : stackoverflow.com/questions/13289777/...
Nakilon

8
이것은 창에 특정한 것 같습니다. Linux의 대체 방법은 무엇입니까?
Insane Coder

84

python3 및 python2 모두 pyautogui( pip install pyautogui)를 사용할 수 있습니다.

from pyautogui import press, typewrite, hotkey

press('a')
typewrite('quick brown fox')
hotkey('ctrl', 'w')

또한 Windows, OSX 및 Ubuntu LTS와 교차 플랫폼입니다.


1
press미디어 키에서도 작동합니다. 나는 내 컴퓨터를 음소거 사용press('volumemute')
CornSmith

3
이것은 작동하지만 허용되는 답변보다 느립니다. (매우 낮은 대기 시간을 필요로 내 응용 프로그램에 대한 너무 느린.)
TimH - Codidact

응용 프로그램이 pyautogui를 통해 명령을 수락하지 않는 특정 상황에 부딪 혔지만 cytpes는 지속적으로 작동하는 것 같습니다.
Allison Wilson

1
이 pyautogui 패키지는 크로스 플랫폼이며 Mac과 Windows에서 작동합니다
Charles Chow

@CharlesChow 좋은 전화, 사람들에게 주목할 가치가 있으므로 답변에 추가했습니다. 또한 Ubuntu에서도 작동합니다 (LTS 이상은 github에
따름

11

user648852의 아이디어는 적어도 나를 위해 OS X에서 잘 작동합니다. 여기에 코드가 있습니다.

#!/usr/bin/env python

import time
from Quartz.CoreGraphics import CGEventCreateKeyboardEvent
from Quartz.CoreGraphics import CGEventPost

# Python releases things automatically, using CFRelease will result in a scary error
#from Quartz.CoreGraphics import CFRelease

from Quartz.CoreGraphics import kCGHIDEventTap

# From http://stackoverflow.com/questions/281133/controlling-the-mouse-from-python-in-os-x
# and from https://developer.apple.com/library/mac/documentation/Carbon/Reference/QuartzEventServicesRef/index.html#//apple_ref/c/func/CGEventCreateKeyboardEvent


def KeyDown(k):
    keyCode, shiftKey = toKeyCode(k)

    time.sleep(0.0001)

    if shiftKey:
        CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, 0x38, True))
        time.sleep(0.0001)

    CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, keyCode, True))
    time.sleep(0.0001)

    if shiftKey:
        CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, 0x38, False))
        time.sleep(0.0001)

def KeyUp(k):
    keyCode, shiftKey = toKeyCode(k)

    time.sleep(0.0001)

    CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, keyCode, False))
    time.sleep(0.0001)

def KeyPress(k):
    keyCode, shiftKey = toKeyCode(k)

    time.sleep(0.0001)

    if shiftKey:
        CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, 0x38, True))
        time.sleep(0.0001)

    CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, keyCode, True))
    time.sleep(0.0001)

    CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, keyCode, False))
    time.sleep(0.0001)

    if shiftKey:
        CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, 0x38, False))
        time.sleep(0.0001)



# From http://stackoverflow.com/questions/3202629/where-can-i-find-a-list-of-mac-virtual-key-codes

def toKeyCode(c):
    shiftKey = False
    # Letter
    if c.isalpha():
        if not c.islower():
            shiftKey = True
            c = c.lower()

    if c in shiftChars:
        shiftKey = True
        c = shiftChars[c]
    if c in keyCodeMap:
        keyCode = keyCodeMap[c]
    else:
        keyCode = ord(c)
    return keyCode, shiftKey

shiftChars = {
    '~': '`',
    '!': '1',
    '@': '2',
    '#': '3',
    '$': '4',
    '%': '5',
    '^': '6',
    '&': '7',
    '*': '8',
    '(': '9',
    ')': '0',
    '_': '-',
    '+': '=',
    '{': '[',
    '}': ']',
    '|': '\\',
    ':': ';',
    '"': '\'',
    '<': ',',
    '>': '.',
    '?': '/'
}


keyCodeMap = {
    'a'                 : 0x00,
    's'                 : 0x01,
    'd'                 : 0x02,
    'f'                 : 0x03,
    'h'                 : 0x04,
    'g'                 : 0x05,
    'z'                 : 0x06,
    'x'                 : 0x07,
    'c'                 : 0x08,
    'v'                 : 0x09,
    'b'                 : 0x0B,
    'q'                 : 0x0C,
    'w'                 : 0x0D,
    'e'                 : 0x0E,
    'r'                 : 0x0F,
    'y'                 : 0x10,
    't'                 : 0x11,
    '1'                 : 0x12,
    '2'                 : 0x13,
    '3'                 : 0x14,
    '4'                 : 0x15,
    '6'                 : 0x16,
    '5'                 : 0x17,
    '='                 : 0x18,
    '9'                 : 0x19,
    '7'                 : 0x1A,
    '-'                 : 0x1B,
    '8'                 : 0x1C,
    '0'                 : 0x1D,
    ']'                 : 0x1E,
    'o'                 : 0x1F,
    'u'                 : 0x20,
    '['                 : 0x21,
    'i'                 : 0x22,
    'p'                 : 0x23,
    'l'                 : 0x25,
    'j'                 : 0x26,
    '\''                : 0x27,
    'k'                 : 0x28,
    ';'                 : 0x29,
    '\\'                : 0x2A,
    ','                 : 0x2B,
    '/'                 : 0x2C,
    'n'                 : 0x2D,
    'm'                 : 0x2E,
    '.'                 : 0x2F,
    '`'                 : 0x32,
    'k.'                : 0x41,
    'k*'                : 0x43,
    'k+'                : 0x45,
    'kclear'            : 0x47,
    'k/'                : 0x4B,
    'k\n'               : 0x4C,
    'k-'                : 0x4E,
    'k='                : 0x51,
    'k0'                : 0x52,
    'k1'                : 0x53,
    'k2'                : 0x54,
    'k3'                : 0x55,
    'k4'                : 0x56,
    'k5'                : 0x57,
    'k6'                : 0x58,
    'k7'                : 0x59,
    'k8'                : 0x5B,
    'k9'                : 0x5C,

    # keycodes for keys that are independent of keyboard layout
    '\n'                : 0x24,
    '\t'                : 0x30,
    ' '                 : 0x31,
    'del'               : 0x33,
    'delete'            : 0x33,
    'esc'               : 0x35,
    'escape'            : 0x35,
    'cmd'               : 0x37,
    'command'           : 0x37,
    'shift'             : 0x38,
    'caps lock'         : 0x39,
    'option'            : 0x3A,
    'ctrl'              : 0x3B,
    'control'           : 0x3B,
    'right shift'       : 0x3C,
    'rshift'            : 0x3C,
    'right option'      : 0x3D,
    'roption'           : 0x3D,
    'right control'     : 0x3E,
    'rcontrol'          : 0x3E,
    'fun'               : 0x3F,
    'function'          : 0x3F,
    'f17'               : 0x40,
    'volume up'         : 0x48,
    'volume down'       : 0x49,
    'mute'              : 0x4A,
    'f18'               : 0x4F,
    'f19'               : 0x50,
    'f20'               : 0x5A,
    'f5'                : 0x60,
    'f6'                : 0x61,
    'f7'                : 0x62,
    'f3'                : 0x63,
    'f8'                : 0x64,
    'f9'                : 0x65,
    'f11'               : 0x67,
    'f13'               : 0x69,
    'f16'               : 0x6A,
    'f14'               : 0x6B,
    'f10'               : 0x6D,
    'f12'               : 0x6F,
    'f15'               : 0x71,
    'help'              : 0x72,
    'home'              : 0x73,
    'pgup'              : 0x74,
    'page up'           : 0x74,
    'forward delete'    : 0x75,
    'f4'                : 0x76,
    'end'               : 0x77,
    'f2'                : 0x78,
    'page down'         : 0x79,
    'pgdn'              : 0x79,
    'f1'                : 0x7A,
    'left'              : 0x7B,
    'right'             : 0x7C,
    'down'              : 0x7D,
    'up'                : 0x7E
}

6

lib 키보드를 사용해 보았는데 Windows에서 잘 작동합니다. 아래 줄은 브라우저에서 탭을 전환하는 데 도움이됩니다.

keyboard.press_and_release('ctrl+tab')

MAC에서도 잘 작동합니다. 나는 리눅스를 테스트하지 않았지만 작동 할 것입니다.
Davoud Taghawi-Nejad

5

나는 똑같은 문제가 있었고 ctypes를 사용하는 자체 라이브러리를 만들었습니다.

"""
< --- CTRL by [object Object] --- >
Only works on windows.
Some characters only work with a US standard keyboard.
Some parts may also only work in python 32-bit.
"""

#--- Setup ---#
from ctypes import *
from time import sleep
user32 = windll.user32
kernel32 = windll.kernel32
delay = 0.01

####################################
###---KEYBOARD CONTROL SECTION---###
####################################

#--- Key Code Variables ---#
class key:
        cancel = 0x03
        backspace = 0x08
        tab = 0x09
        enter = 0x0D
        shift = 0x10
        ctrl = 0x11
        alt = 0x12
        capslock = 0x14
        esc = 0x1B
        space = 0x20
        pgup = 0x21
        pgdown = 0x22
        end = 0x23
        home = 0x24
        leftarrow = 0x26
        uparrow = 0x26
        rightarrow = 0x27
        downarrow = 0x28
        select = 0x29
        print = 0x2A
        execute = 0x2B
        printscreen = 0x2C
        insert = 0x2D
        delete = 0x2E
        help = 0x2F
        num0 = 0x30
        num1 = 0x31
        num2 = 0x32
        num3 = 0x33
        num4 = 0x34
        num5 = 0x35
        num6 = 0x36
        num7 = 0x37
        num8 = 0x38
        num9 = 0x39
        a = 0x41
        b = 0x42
        c = 0x43
        d = 0x44
        e = 0x45
        f = 0x46
        g = 0x47
        h = 0x48
        i = 0x49
        j = 0x4A
        k = 0x4B
        l = 0x4C
        m = 0x4D
        n = 0x4E
        o = 0x4F
        p = 0x50
        q = 0x51
        r = 0x52
        s = 0x53
        t = 0x54
        u = 0x55
        v = 0x56
        w = 0x57
        x = 0x58
        y = 0x59
        z = 0x5A
        leftwin = 0x5B
        rightwin = 0x5C
        apps = 0x5D
        sleep = 0x5F
        numpad0 = 0x60
        numpad1 = 0x61
        numpad3 = 0x63
        numpad4 = 0x64
        numpad5 = 0x65
        numpad6 = 0x66
        numpad7 = 0x67
        numpad8 = 0x68
        numpad9 = 0x69
        multiply = 0x6A
        add = 0x6B
        seperator = 0x6C
        subtract = 0x6D
        decimal = 0x6E
        divide = 0x6F
        F1 = 0x70
        F2 = 0x71
        F3 = 0x72
        F4 = 0x73
        F5 = 0x74
        F6 = 0x75
        F7 = 0x76
        F8 = 0x77
        F9 = 0x78
        F10 = 0x79
        F11 = 0x7A
        F12 = 0x7B
        F13 = 0x7C
        F14 = 0x7D
        F15 = 0x7E
        F16 = 0x7F
        F17 = 0x80
        F19 = 0x82
        F20 = 0x83
        F21 = 0x84
        F22 = 0x85
        F23 = 0x86
        F24 = 0x87
        numlock = 0x90
        scrolllock = 0x91
        leftshift = 0xA0
        rightshift = 0xA1
        leftctrl = 0xA2
        rightctrl = 0xA3
        leftmenu = 0xA4
        rightmenu = 0xA5
        browserback = 0xA6
        browserforward = 0xA7
        browserrefresh = 0xA8
        browserstop = 0xA9
        browserfavories = 0xAB
        browserhome = 0xAC
        volumemute = 0xAD
        volumedown = 0xAE
        volumeup = 0xAF
        nexttrack = 0xB0
        prevoustrack = 0xB1
        stopmedia = 0xB2
        playpause = 0xB3
        launchmail = 0xB4
        selectmedia = 0xB5
        launchapp1 = 0xB6
        launchapp2 = 0xB7
        semicolon = 0xBA
        equals = 0xBB
        comma = 0xBC
        dash = 0xBD
        period = 0xBE
        slash = 0xBF
        accent = 0xC0
        openingsquarebracket = 0xDB
        backslash = 0xDC
        closingsquarebracket = 0xDD
        quote = 0xDE
        play = 0xFA
        zoom = 0xFB
        PA1 = 0xFD
        clear = 0xFE

#--- Keyboard Control Functions ---#

# Category variables
letters = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
shiftsymbols = "~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?"

# Presses and releases the key
def press(key):
        user32.keybd_event(key, 0, 0, 0)
        sleep(delay)
        user32.keybd_event(key, 0, 2, 0)
        sleep(delay)

# Holds a key
def hold(key):
        user32.keybd_event(key, 0, 0, 0)
        sleep(delay)

# Releases a key
def release(key):
        user32.keybd_event(key, 0, 2, 0)
        sleep(delay)

# Types out a string
def typestr(sentence):
        for letter in sentence:
                shift = letter in shiftsymbols
                fixedletter = "space"
                if letter == "`" or letter == "~":
                        fixedletter = "accent"
                elif letter == "1" or letter == "!":
                        fixedletter = "num1"
                elif letter == "2" or letter == "@":
                        fixedletter = "num2"
                elif letter == "3" or letter == "#":
                        fixedletter = "num3"
                elif letter == "4" or letter == "$":
                        fixedletter = "num4"
                elif letter == "5" or letter == "%":
                        fixedletter = "num5"
                elif letter == "6" or letter == "^":
                        fixedletter = "num6"
                elif letter == "7" or letter == "&":
                        fixedletter = "num7"
                elif letter == "8" or letter == "*":
                        fixedletter = "num8"
                elif letter == "9" or letter == "(":
                        fixedletter = "num9"
                elif letter == "0" or letter == ")":
                        fixedletter = "num0"
                elif letter == "-" or letter == "_":
                        fixedletter = "dash"
                elif letter == "=" or letter == "+":
                        fixedletter = "equals"
                elif letter in letters:
                        fixedletter = letter.lower()
                elif letter == "[" or letter == "{":
                        fixedletter = "openingsquarebracket"
                elif letter == "]" or letter == "}":
                        fixedletter = "closingsquarebracket"
                elif letter == "\\" or letter == "|":
                        fixedletter == "backslash"
                elif letter == ";" or letter == ":":
                        fixedletter = "semicolon"
                elif letter == "'" or letter == "\"":
                        fixedletter = "quote"
                elif letter == "," or letter == "<":
                        fixedletter = "comma"
                elif letter == "." or letter == ">":
                        fixedletter = "period"
                elif letter == "/" or letter == "?":
                        fixedletter = "slash"
                elif letter == "\n":
                        fixedletter = "enter"
                keytopress = eval("key." + str(fixedletter))
                if shift:
                        hold(key.shift)
                        press(keytopress)
                        release(key.shift)
                else:
                        press(keytopress)

#--- Mouse Variables ---#
                        
class mouse:
        left = [0x0002, 0x0004]
        right = [0x0008, 0x00010]
        middle = [0x00020, 0x00040]

#--- Mouse Control Functions ---#

# Moves mouse to a position
def move(x, y):
        user32.SetCursorPos(x, y)

# Presses and releases mouse
def click(button):
        user32.mouse_event(button[0], 0, 0, 0, 0)
        sleep(delay)
        user32.mouse_event(button[1], 0, 0, 0, 0)
        sleep(delay)

# Holds a mouse button
def holdclick(button):
        user32.mouse_event(button[0], 0, 0, 0, 0)
        sleep(delay)

# Releases a mouse button
def releaseclick(button):
        user32.mouse_event(button[1])
        sleep(delay)

3

맥 OS

다음은 코드 예제가있는 클래스 형식의 @Phylliida 답변 의 더 완전한 버전입니다 .

#!/usr/bin/python
# Script simulating keyboard events in macOS.
# See: https://stackoverflow.com/q/13564851/55075

import sys
import time
from Quartz.CoreGraphics import CGEventCreateKeyboardEvent
from Quartz.CoreGraphics import CGEventPost
from Quartz.CoreGraphics import kCGHIDEventTap
#from Quartz.CoreGraphics import CFRelease # Python releases things automatically.

class Keyboard():
    shiftChars = {
        '~': '`',
        '!': '1',
        '@': '2',
        '#': '3',
        '$': '4',
        '%': '5',
        '^': '6',
        '&': '7',
        '*': '8',
        '(': '9',
        ')': '0',
        '_': '-',
        '+': '=',
        '{': '[',
        '}': ']',
        '|': '\\',
        ':': ';',
        '"': '\'',
        '<': ',',
        '>': '.',
        '?': '/'
    }


    keyCodeMap = {
        'a'              : 0x00,
        's'              : 0x01,
        'd'              : 0x02,
        'f'              : 0x03,
        'h'              : 0x04,
        'g'              : 0x05,
        'z'              : 0x06,
        'x'              : 0x07,
        'c'              : 0x08,
        'v'              : 0x09,
        'b'              : 0x0B,
        'q'              : 0x0C,
        'w'              : 0x0D,
        'e'              : 0x0E,
        'r'              : 0x0F,
        'y'              : 0x10,
        't'              : 0x11,
        '1'              : 0x12,
        '2'              : 0x13,
        '3'              : 0x14,
        '4'              : 0x15,
        '6'              : 0x16,
        '5'              : 0x17,
        '='              : 0x18,
        '9'              : 0x19,
        '7'              : 0x1A,
        '-'              : 0x1B,
        '8'              : 0x1C,
        '0'              : 0x1D,
        ']'              : 0x1E,
        'o'              : 0x1F,
        'u'              : 0x20,
        '['              : 0x21,
        'i'              : 0x22,
        'p'              : 0x23,
        'l'              : 0x25,
        'j'              : 0x26,
        '\''             : 0x27,
        'k'              : 0x28,
        ';'              : 0x29,
        '\\'             : 0x2A,
        ','              : 0x2B,
        '/'              : 0x2C,
        'n'              : 0x2D,
        'm'              : 0x2E,
        '.'              : 0x2F,
        '`'              : 0x32,
        'k.'             : 0x41,
        'k*'             : 0x43,
        'k+'             : 0x45,
        'kclear'         : 0x47,
        'k/'             : 0x4B,
        'k\n'            : 0x4C,
        'k-'             : 0x4E,
        'k='             : 0x51,
        'k0'             : 0x52,
        'k1'             : 0x53,
        'k2'             : 0x54,
        'k3'             : 0x55,
        'k4'             : 0x56,
        'k5'             : 0x57,
        'k6'             : 0x58,
        'k7'             : 0x59,
        'k8'             : 0x5B,
        'k9'             : 0x5C,

        # keycodes for keys that are independent of keyboard layout
        '\n'             : 0x24,
        '\t'             : 0x30,
        ' '              : 0x31,
        'del'            : 0x33,
        'delete'         : 0x33,
        'esc'            : 0x35,
        'escape'         : 0x35,
        'cmd'            : 0x37,
        'command'        : 0x37,
        'shift'          : 0x38,
        'caps lock'      : 0x39,
        'option'         : 0x3A,
        'ctrl'           : 0x3B,
        'control'        : 0x3B,
        'right shift'    : 0x3C,
        'rshift'         : 0x3C,
        'right option'   : 0x3D,
        'roption'        : 0x3D,
        'right control'  : 0x3E,
        'rcontrol'       : 0x3E,
        'fun'            : 0x3F,
        'function'       : 0x3F,
        'f17'            : 0x40,
        'volume up'      : 0x48,
        'volume down'    : 0x49,
        'mute'           : 0x4A,
        'f18'            : 0x4F,
        'f19'            : 0x50,
        'f20'            : 0x5A,
        'f5'             : 0x60,
        'f6'             : 0x61,
        'f7'             : 0x62,
        'f3'             : 0x63,
        'f8'             : 0x64,
        'f9'             : 0x65,
        'f11'            : 0x67,
        'f13'            : 0x69,
        'f16'            : 0x6A,
        'f14'            : 0x6B,
        'f10'            : 0x6D,
        'f12'            : 0x6F,
        'f15'            : 0x71,
        'help'           : 0x72,
        'home'           : 0x73,
        'pgup'           : 0x74,
        'page up'        : 0x74,
        'forward delete' : 0x75,
        'f4'             : 0x76,
        'end'            : 0x77,
        'f2'             : 0x78,
        'page down'      : 0x79,
        'pgdn'           : 0x79,
        'f1'             : 0x7A,
        'left'           : 0x7B,
        'right'          : 0x7C,
        'down'           : 0x7D,
        'up'             : 0x7E
    }

    # See: https://stackoverflow.com/q/3202629/55075
    def toKeyCode(self, c):
        shiftKey = False
        # Letter
        if c.isalpha():
            if not c.islower():
                shiftKey = True
                c = c.lower()
        if c in Keyboard.shiftChars:
            shiftKey = True
            c = Keyboard.shiftChars[c]
        if c in Keyboard.keyCodeMap:
            keyCode = Keyboard.keyCodeMap[c]
        else:
            keyCode = ord(c)
        return keyCode, shiftKey

    def KeyDown(self, k):
        keyCode, shiftKey = self.toKeyCode(k)

        time.sleep(0.0001)

        if shiftKey:
            CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, 0x38, True))
            time.sleep(0.0001)

        CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, keyCode, True))
        time.sleep(0.0001)

        if shiftKey:
            CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, 0x38, False))
            time.sleep(0.0001)

    def KeyUp(self, k):
        keyCode, shiftKey = self.toKeyCode(k)

        time.sleep(0.0001)

        CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, keyCode, False))
        time.sleep(0.0001)

    def KeyPress(self, k):
        keyCode, shiftKey = self.toKeyCode(k)

        time.sleep(0.0001)

        if shiftKey:
            CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, 0x38, True))
            time.sleep(0.0001)

        CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, keyCode, True))
        time.sleep(0.0001)

        CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, keyCode, False))
        time.sleep(0.0001)

        if shiftKey:
            CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, 0x38, False))
            time.sleep(0.0001)

    def Type(self, text):
        for key in text:
            self.KeyDown(key)
            self.KeyUp(key)

위의 클래스를 사용하는 데모 코드는 다음과 같습니다.

# DEMO
if __name__ == '__main__':
    keyboard = Keyboard()
    if sys.platform == "darwin":
        keyboard.Type('Hello World!')
    elif sys.platform == "win32":
        print("Error: Platform not supported!")

Hello World!현재 창에 텍스트 입력을 시뮬레이션 합니다.

위의 코드를 쉘 스크립트로 실행할 수 있습니다. keyboard.py파일 링크를 확인하십시오 .


2

모든 플랫폼은 키보드 이벤트를 생성 할 수있는 다른 접근 방식을 가질 것입니다. 이는 각각 시스템 라이브러리 (및 시스템 확장)를 사용해야하기 때문입니다. 크로스 플랫폼 솔루션의 경우 이러한 솔루션 각각을 가져 와서 적절한 접근 방식을 수행하기 위해 플랫폼 검사로 래핑해야합니다.

Windows의 경우 pywin32 확장 을 사용할 수 있습니다 . win32api.keybd_event

win32api.keybd_event

keybd_event (bVk, bScan, dwFlags, dwExtraInfo)

키보드 이벤트 시뮬레이션

매개 변수

bVk : BYTE-가상 키 코드
bScan : BYTE-하드웨어 스캔 코드
dwFlags = 0 :
DWORD- 다양한 기능 옵션을 지정하는 플래그 dwExtraInfo = 0 : DWORD-키 입력과 관련된 추가 데이터

pywin32를 사용하지 않았으므로 올바르게 사용하는 방법을 조사해야합니다.


2

Windows 전용 : Ironpython 또는 cPython이 Windows에서 .NET 프레임 워크에 액세스 할 수 있도록 허용 하는 라이브러리 를 사용할 수 있습니다 . 그런 다음 .NET 의 sendkeys 클래스 또는보다 일반적인 send 를 사용하여 키 입력을 시뮬레이션합니다.

OS X 전용 : 사용 PyObjC는 다음 사용 사용하는 CGEventCreateKeyboardEvent전화.

전체 공개 : 저는 Python을 사용하는 OS X에서만이 작업을 수행했지만 .NET sendkeys (C # 사용)를 사용했으며 훌륭하게 작동합니다.


IronPython의 .Net SendKeys (데스크톱 앱의 수락 테스트 프레임 워크 용)를 사용했으며 훌륭하게 작동했습니다.
Jonathan Hartley 2012

1
python for .net. aa 솔루션, 어떻게 sendkeys. 이것의 예를 들어 주실 수 있습니까?
Inbar Rose 2012

2

Python2.7 (windows32)의 경우 pywin32-223 만 설치 했습니다 . 그리고 저는 간단한 파이썬 코드를 작성했습니다.

import win32api
import time
import win32con

# simulate the pressing-DOWN "ARROW key" of 200 times

for i in range(200):
   time.sleep(0.5)
   win32api.keybd_event(0x28, 0,0,0)
   time.sleep(.05)
   win32api.keybd_event(0x28,0 ,win32con.KEYEVENTF_KEYUP ,0)

코드를 실행하고 즉시 메모장 창 (텍스트가 이미 존재하는 곳)으로 이동하여 맨 윗줄에 커서를 놓으면 확인할 수 있습니다.


똑같은 keybd_event 함수가 이미 ctypes에 존재합니다
object-Object

ctypes.windll.user32.keybd_event (0x01, 0, 0, 0)
object-Object

0

추천 답변 코드와 관련하여

내 봇의 경우 권장 답변이 작동하지 않았습니다. dwFlags에서 KEYEVENTF_SCANCODE를 사용해야하는 Chrome을 사용하고 있기 때문입니다.

그의 코드가 작동하도록하려면 다음 코드 블록을 수정해야했습니다.

class KEYBDINPUT(ctypes.Structure):
    _fields_ = (("wVk",         wintypes.WORD),
                ("wScan",       wintypes.WORD),
                ("dwFlags",     wintypes.DWORD),
                ("time",        wintypes.DWORD),
                ("dwExtraInfo", wintypes.ULONG_PTR))

    def __init__(self, *args, **kwds):
        super(KEYBDINPUT, self).__init__(*args, **kwds)
        # some programs use the scan code even if KEYEVENTF_SCANCODE
        # isn't set in dwFflags, so attempt to map the correct code.
        #if not self.dwFlags & KEYEVENTF_UNICODE:l
            #self.wScan = user32.MapVirtualKeyExW(self.wVk,
                                                 #MAPVK_VK_TO_VSC, 0)
            # ^MAKE SURE YOU COMMENT/REMOVE THIS CODE^

def PressKey(keyCode):
    input = INPUT(type=INPUT_KEYBOARD,
              ki=KEYBDINPUT(wScan=keyCode,
                            dwFlags=KEYEVENTF_SCANCODE))
    user32.SendInput(1, ctypes.byref(input), ctypes.sizeof(input))

def ReleaseKey(keyCode):
    input = INPUT(type=INPUT_KEYBOARD,
              ki=KEYBDINPUT(wScan=keyCode,
                            dwFlags=KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP))
    user32.SendInput(1, ctypes.byref(input), ctypes.sizeof(input))

time.sleep(5) # sleep to open browser tab
PressKey(0x26) # press right arrow key
time.sleep(2) # hold for 2 seconds
ReleaseKey(0x26) # release right arrow key

이것이 누군가의 두통에 도움이되기를 바랍니다!


0
    def keyboardevent():
         keyboard.press_and_release('a')
         keyboard.press_and_release('shift + b')
         
    keyboardevent()

2
StackOverflow에 오신 것을 환영합니다. 이 코드가 문제를 해결할 수 있지만 문제를 해결하는 방법과 이유에 대한 설명을 포함하여 게시물의 품질을 향상시키는 데 실제로 도움이되며 더 많은 찬성 투표가 발생할 수 있습니다. 지금 질문하는 사람뿐만 아니라 미래에 독자를 위해 질문에 답하고 있다는 것을 기억하십시오. 답변을 편집하여 설명을 추가하고 적용되는 제한 및 가정에 대한 표시를 제공하십시오.
Ruli
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.