首页 > 解决方案 > pynput 键盘记录器不写入文件

问题描述

我对这个键盘记录程序有疑问。它必须写入文件,但它不这样做。怎么了?

程序必须听键盘并将其写入文件(之前,检查文件是否存在)。但它不会写入文件,它只会创建文件。

from pynput import keyboard
import os

if os.path.exists("prova3.txt") == True:
    f = open("prova3.txt","a")
else:
    f = open("prova3.txt","x")

def on_press(key):
    try:
        f.writelines("///key [ {0} ] pressed ///".format(
            key.char))
    except AttributeError:
        f.writelines("///special key {0} pressed///".format(
            key))

def on_release(key):
    f.writelines(["///key [ {0} ] released ///".format(
        key)])

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

标签: pythonpython-3.xkeyloggerpynput

解决方案


首先,确保您注意到pynput 文档中的警告:

启动键盘侦听器可能会受到您平台上的一些限制。

如果你像我一样在 Mac 上,那么你必须这样做:

  • 该进程必须以 root 身份运行。
  • 您的应用程序必须在启用辅助设备访问权限下列入白名单。

对于第二个项目,请从相关的 SO 帖子中检查这些步骤。

现在,对于实际的文件写入问题,一种解决方案是调用f.flush()后调用f.writelines,以确保数据实际写入文件。(有关一些解释,请参阅此相关帖子:python 的 file.flush() 到底在做什么?)。我不熟悉 pynput 的底层实现,但文档说它使用线程,这似乎会影响文件 I/O。f.close()完成文件后调用也是一个好习惯。

from pynput import keyboard

if os.path.exists("prova3.txt"):
    f = open("prova3.txt", "a")
else:
    f = open("prova3.txt", "x")

def on_press(key):
    try:
        f.writelines("///key [ {0} ] pressed ///".format(
            key.char))
    except AttributeError:
        f.writelines("///special key {0} pressed///".format(
            key))
        f.flush()

def on_release(key):
    f.writelines(["///key [ {0} ] released ///".format(
        key)])
    f.flush()

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

f.close()

另一种更好的做法是在写入文件时使用with语句。这将f和 pynputlistener放在同一个上下文中。flush通过这种方式,不需要调用(但如果你愿意,你仍然可以)。

from pynput import keyboard

with open("prova3.txt", "a") as f:
    def on_press(key):
        try:
            f.writelines("///key [ {0} ] pressed ///".format(
                key.char))
        except AttributeError:
            f.writelines("///special key {0} pressed///".format(
                key))

    def on_release(key):
        f.writelines(["///key [ {0} ] released ///".format(
            key)])

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

推荐阅读