本文目录导读:

我来介绍几种监控键盘操作的方法,包括不同平台的实现方案:
Python 方案(跨平台)
使用 pynput(推荐)
from pynput import keyboard
import logging
from datetime import datetime
# 设置日志
logging.basicConfig(
filename='keyboard_log.txt',
level=logging.INFO,
format='%(asctime)s: %(message)s'
)
class KeyMonitor:
def __init__(self):
self.listener = None
self.key_history = []
def on_press(self, key):
try:
# 记录普通字符键
current_keys = []
if hasattr(key, 'char'):
current_keys.append(key.char)
print(f'按下: {key.char}')
logging.info(f'按下键: {key.char}')
else:
# 特殊按键
current_keys.append(str(key))
print(f'特殊键: {key}')
logging.info(f'特殊键: {key}')
# 存储历史
self.key_history.append({
'key': current_keys,
'time': datetime.now().isoformat()
})
except Exception as e:
print(f"错误: {e}")
def on_release(self, key):
print(f'释放: {key}')
# 按 ESC 键退出
if key == keyboard.Key.esc:
print('监控结束')
return False
def start(self):
print("键盘监控已启动,按 ESC 键退出...")
with keyboard.Listener(
on_press=self.on_press,
on_release=self.on_release
) as listener:
self.listener = listener
listener.join()
# 使用示例
monitor = KeyMonitor()
monitor.start()
使用 keyboard 库(Windows/Linux)
import keyboard
import json
import time
from datetime import datetime
class KeyboardMonitor:
def __init__(self):
self.events = []
self.start_time = time.time()
def start_monitoring(self):
print("开始监控键盘,按 Ctrl+C 停止...")
# 记录所有键盘事件
keyboard.hook(self.on_key_event)
try:
keyboard.wait('ctrl+c') # 等待Ctrl+C
except KeyboardInterrupt:
pass
finally:
keyboard.unhook_all()
self.save_to_file()
def on_key_event(self, event):
"""处理键盘事件"""
event_data = {
'event_type': event.event_type, # 'down' 或 'up'
'key': event.name,
'scan_code': event.scan_code,
'time': datetime.now().isoformat(),
'elapsed_ms': int((time.time() - self.start_time) * 1000)
}
self.events.append(event_data)
print(f"{event_data['event_type']}: {event_data['key']}")
def save_to_file(self):
"""保存记录到文件"""
with open('keyboard_events.json', 'w') as f:
json.dump(self.events, f, indent=2)
print(f"已保存 {len(self.events)} 个键盘事件")
# 使用示例
monitor = KeyboardMonitor()
monitor.start_monitoring()
JavaScript 方案(浏览器)
// 浏览器键盘监听器
class BrowserKeyMonitor {
constructor() {
this.events = [];
this.listeners = [];
}
start() {
// 监听键盘事件
const keyDownHandler = (event) => {
this.events.push({
type: 'keydown',
key: event.key,
code: event.code,
keyCode: event.keyCode,
timestamp: new Date().toISOString()
});
console.log(`KeyDown: ${event.key}`);
};
const keyUpHandler = (event) => {
this.events.push({
type: 'keyup',
key: event.key,
code: event.code,
timestamp: new Date().toISOString()
});
console.log(`KeyUp: ${event.key}`);
};
const keyPressHandler = (event) => {
if (event.key) {
this.events.push({
type: 'keypress',
key: event.key,
timestamp: new Date().toISOString()
});
}
};
// 添加有效输入的检查(检测是否活动窗口)
const isEditable = (target) => {
const tagName = target.tagName.toLowerCase();
return ['input', 'textarea', 'select'].includes(tagName) ||
target.isContentEditable;
};
// 添加监听器
document.addEventListener('keydown', (e) => {
if (!isEditable(e.target)) {
keyDownHandler(e);
}
});
document.addEventListener('keyup', (e) => {
if (!isEditable(e.target)) {
keyUpHandler(e);
}
});
console.log('键盘监控已启动');
}
stop() {
this.listeners.forEach(listener => listener.remove());
console.log('键盘监控已停止');
}
getEvents() {
return this.events;
}
}
// 使用示例
const monitor = new BrowserKeyMonitor();
monitor.start();
// 停止监控
// monitor.stop();
Shell 脚本(Linux)
#!/bin/bash
# keyboard_monitor.sh
LOG_FILE="/tmp/keyboard_monitor.log"
MONITOR_TIME=60 # 监控60秒
echo "开始监控键盘,将记录到 $LOG_FILE"
echo "时间: $(date)"
# 清理旧的日志
> $LOG_FILE
# 使用 Linux 的输入设备监控
sudo cat /dev/input/event* | while read -r line; do
echo "$(date +'%Y-%m-%d %H:%M:%S') $line" >> $LOG_FILE
done &
MONITOR_PID=$!
# 检查 /proc/interrupts 键盘中断
watch -n 1 "grep -E 'i8042|atkbd' /proc/interrupts | awk '{print \$1, \$NF, \$NF}'"
# 或者使用 evtest 工具(需要安装)
# sudo evtest /dev/input/eventX
# 监控 syslog 中的键盘事件
tail -f /var/log/syslog | grep -i keyboard &
echo "监控完成,日志保存在 $LOG_FILE"
Windows PowerShell 脚本
# keyboard_monitor.ps1
Add-Type -AssemblyName System.Windows.Forms
# 创建键盘钩子
$script:keyLog = @()
$script:monitorRunning = $true
# Windows API 钩子
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class KeyMonitor {
[DllImport("user32.dll")]
public static extern bool GetAsyncKeyState(int keyCode);
[DllImport("user32.dll")]
public static extern short GetKeyState(int keyCode);
}
"@
# 需要监控的按键列表
$keys = @(
0x41, # A
0x42, # B
0x43, # C
0x51, # Q
0x52, # R
0x54, # T
0x5A # Z
)
Write-Host "键盘监控已启动,按 Ctrl+C 停止..."
try {
while ($script:monitorRunning) {
foreach ($key in $keys) {
if ([KeyMonitor]::GetAsyncKeyState($key)) {
$keyInfo = [System.Text.Encoding]::ASCII.GetString([byte]$key)
$logEntry = @{
Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Key = $keyInfo
KeyCode = "0x$($key.ToString("X2"))"
ProcessName = (Get-Process | Where-Object {$_.MainWindowHandle -ne 0} |
Select-Object -First 1).ProcessName
}
$script:keyLog += $logEntry
Write-Host "按下: $keyInfo - $($logEntry.Timestamp)"
Start-Sleep -Milliseconds 100
}
}
Start-Sleep -Milliseconds 50
}
} catch {
Write-Host "监控异常: $_"
} finally {
# 保存日志
$script:keyLog | Export-Csv -Path "keyboard_log.csv" -NoTypeInformation
Write-Host "日志已保存到 keyboard_log.csv"
}
Go 语言方案(跨平台)
package main
import (
"fmt"
"log"
"os"
"os/signal"
"syscall"
"time"
"github.com/eiannone/keyboard"
)
func main() {
// 打开键盘监听
if err := keyboard.Open(); err != nil {
log.Fatal(err)
}
defer keyboard.Close()
logFile, err := os.OpenFile("keyboard_log.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatal(err)
}
defer logFile.Close()
logger := log.New(logFile, "", log.LstdFlags)
fmt.Println("键盘监控已启动,按 ESC 退出...")
// 信号处理
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-sigChan
fmt.Println("\n监控停止")
os.Exit(0)
}()
// 主循环
for {
char, key, err := keyboard.GetKey()
if err != nil {
log.Fatal(err)
}
timestamp := time.Now().Format("2006-01-02 15:04:05")
if key == keyboard.KeyEsc {
fmt.Println("\n监控结束")
break
}
if key != 0 {
// 特殊按键
logEntry := fmt.Sprintf("[%s] Key: %v", timestamp, key)
logger.Println(logEntry)
fmt.Printf("特殊键: %v\n", key)
} else if char != 0 {
// 普通字符
logEntry := fmt.Sprintf("[%s] Char: %c", timestamp, char)
logger.Println(logEntry)
fmt.Printf("字符: %c\n", char)
}
time.Sleep(10 * time.Millisecond)
}
}
注意事项
- 权限要求:键盘监控通常需要管理员/root权限
- 隐私问题:确保遵守相关法律法规,不要非法使用
- 性能影响:监控可能会影响系统性能
- 安全考虑:不要将监控数据用于非法用途
进阶功能
# 高级功能示例
import threading
from collections import Counter
from datetime import datetime, timedelta
class AdvancedKeyMonitor:
def __init__(self):
self.keys = []
self.key_counter = Counter()
self.start_time = datetime.now()
self.lock = threading.Lock()
def analyze_patterns(self):
"""分析按键模式"""
if len(self.keys) < 100:
return "数据不足,继续收集..."
with self.lock:
# 最常按的键
top_keys = self.key_counter.most_common(10)
# 按键频率
elapsed = datetime.now() - self.start_time
keys_per_min = len(self.keys) / (elapsed.total_seconds() / 60)
return f"""
键盘使用分析:
- 总按键数: {len(self.keys)}
- 每分钟按键: {keys_per_min:.2f}
- 常用按键: {top_keys[:5]}
- 使用时长: {str(elapsed).split('.')[0]}
"""
选择哪种方案取决于你的需求:
- 跨平台:Python + pynput,Go
- 浏览器监控:JavaScript
- Linux系统:Shell 或 C 程序
- Windows系统:PowerShell 或 C#
记得始终遵守隐私和道德规范!