Search code examples
pythonpython-3.xpynput

Storing keystrokes into text file


I have taken a piece of code from https://pynput.readthedocs.io/en/latest/keyboard.html and modified it so that it stores keystrokes into a text file. However, I get the error message in the output:

ImportError: cannot import name 'keyboard' from 'pynput'

Googling it brings up...

from pynput.keyboard import Key, Listener

...but even this import is not compatible with my code. I have downloaded pynput for python3. The original code from the above link:

from pynput import keyboard
    def on_press(key):
        try:
            print('alphanumeric key {0} pressed'.format(key.char))
        except AttributeError:
            print('special key {0} pressed'.format(key))
    def on_release(key):
        print('{0} released'.format(key))
        if key == keyboard.Key.esc:
            # Stop listener
            return False
    # Collect events until released
    with keyboard.Listener(on_press=on_press,on_release=on_release) as listener:
        listener.join()

The modified code:

import pynput
from pynput import keyboard

def on_press(key):
    with open("keylogger.txt", "a") as f:
        try:
            f.print('alphanumeric key {0} pressed'.format(key.char))
        except AttributeError:
            f.print('special key {0} pressed'.format(key))
def on_release(key):
    with open("keylogger.txt", "a") as f:
        f.print('{0} released'.format(key))
        if key == keyboard.Key.esc:
            # Stop listener
            return False
# Collect events until released
with keyboard.Listener(on_press=on_press,on_release=on_release) as listener:
    listener.join()

Am I missing something that would allow the program to properly store the keystrokes into the text file?


Solution

  • 1st of all, DO NOT name your Python files same as modules.

    ImportError: cannot import name 'keyboard' from 'pynput' (/root/Testing6/Sample6_2/pynput.py) 
    

    Here, Python is looking for keyboard from your pynput script, instead of the actual pynput module.
    See the Module Search Path:

    When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:

    • The directory containing the input script (or the current directory when no file is specified).
    • PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
    • The installation-dependent default.

    Here, Python found a pynput module in the current directory, your script, which obviously isn't the one you want and it indeed does not have the keyboard module. So, you just need to rename it something else (ex. mykeylogger.py). Your current import code should work fine:

    from pynput import keyboard
    

    2nd, there is no f.print. FIle objects do not have a print method.
    Change all those f.print to f.write.

    def on_press(key):
        with open("keylogger.txt", "a") as f:
            try:
                f.write('alphanumeric key {0} pressed'.format(key.char))
            except AttributeError:
                f.write('special key {0} pressed'.format(key))
    

    Last, do take note that pynput has some platform limitations that may cause it to not work. For Linux, you just have to make sure that:

    • An X server must be running.
    • The environment variable $DISPLAY must be set.

    Your program runs fine after that.

    $ python3 mykeylogger.py
    aaabbb
    ^CTraceback (most recent call last):
    ...
    KeyboardInterrupt
    $ cat keylogger.txt
    alphanumeric key a pressed'a' releasedalphanumeric key a pressed'a' releasedalphanumeric key a pressed'a' releasedalphanumeric key b pressed'b' releasedalphanumeric key b pressed'b' releasedalphanumeric key b pressed'b' releasedspecial key Key.enter pressedKey.enter releasedspecial key Key.ctrl pressedalphanumeric key  pressed