Search code examples
pythonkeyboard-eventskeylogger

Duplicates in output with module keyboard


I was working on a keylogger that captures keys with the python module "keyboard". But I have a problem regarding my output. When I type in "Hello World", the output is flase. Like so: "shift-H-shift-e-e-l-l-o-space-W-o-r-l-d-d-enter
Code:

print("starting")
import keyboard                 # imports the keyboard-module
file = open("log.txt", "w")     # creates a file
nZ = 0
keyboard.unhook_all()           # clears all keys that were typed in

def on_key(key):
    file.write(str(key.name) + "\n")    # writes the output to a file
    file.flush()                        # saves the written stuff

while True:
    keyboard.hook(on_key)       # waits for a key typed in
    keyboard.unhook_all()       # again clears all keys that were typed in
    nZ += 1

file.close()

So they are sometimes duplicates and sometimes not. Why is that? Is my computer to slow, is it on the module itself or do I use the wrong function or something similar?

Edit - correct code (Is working better but isn't that good to use because there are still some duplicates in it):

print("starting")
import keyboard                 # imports the keyboard-module
file = open("log.txt", "w")     # creates a file
keyboard.unhook_all()           # clears all keys that were typed in

def on_key(key):
    file.write(str(key.name) + "\n")    # writes the output to a file
    file.flush()                        # saves the written stuff

while True:
    keyboard.on_release(on_key)       # waits for a key typed in
    keyboard.unhook_all()              # again clears all keys that were typed in

file.close() 

** Edit 2 - the most efective way with the module keyboard is the following code:

import keyboard
rk = keyboard.record(until="Esc")
keyboard.play(rk)
 

Solution

  • The problem is that the hook fires, gets unbound, gets rebound and immediately fires again as the key is still pressed.

    You can prevent that by using keyboard.on_release(on_key) instead of keyboard.hook(on_key). This causes the hook only fire when the key is released. This way the key is no longer pressed when the hook is rebound.