PyAutoGUI 是 Python 的自动化控制库,可模拟鼠标、键盘操作,支持 Windows/macOS/Linux,安装前需确保已安装 Python(推荐 3.6+)和 pip。
v基础功能
一、PyAutoGUI 安装
PyAutoGUI 是 Python 的自动化控制库,可模拟鼠标、键盘操作,支持 Windows/macOS/Linux,安装前需确保已安装 Python(推荐 3.6+)和 pip。
1. 基础安装(通用)
打开命令行(CMD/Terminal),执行:
# 基础安装(Windows/macOS/Linux 通用)
pip install pyautogui
# 若系统有多个Python版本,用pip3
pip3 install pyautogui
# 国内源加速(推荐)
pip install pyautogui -i https://pypi.tuna.tsinghua.edu.cn/simple
2. 不同系统的额外依赖
-
Windows:无需额外依赖,安装后直接使用。
-
macOS:需安装 PyObjC(系统交互依赖),执行:
# 先装核心依赖,再装完整PyObjC pip3 install pyobjc-core pip3 install pyobjc此外,macOS 需给终端 / IDE 开启「辅助功能」权限(系统设置 → 隐私与安全性 → 辅助功能),否则无法模拟操作。
-
Linux:需安装截图和 X11 依赖,以 Debian/Ubuntu 为例:
sudo apt-get install scrot python3-xlib
二、PyAutoGUI 核心使用
1. 基础配置(必做)
import pyautogui
# 安全设置:鼠标移到屏幕左上角(0,0)触发异常,终止程序(防止失控)
pyautogui.FAILSAFE = True
# 每次操作后暂停1秒(防止操作过快,便于调试)
pyautogui.PAUSE = 1
2. 屏幕相关操作
(1)获取屏幕尺寸
# 获取屏幕宽高(返回元组:(宽度, 高度))
screen_width, screen_height = pyautogui.size()
print(f"屏幕尺寸:{screen_width}x{screen_height}")
(2)截图操作
# 截取整个屏幕,返回PIL图像对象
screenshot = pyautogui.screenshot()
# 保存截图到本地
screenshot.save("full_screen.png")
# 截取指定区域(x,y 起始坐标,width,height 宽高)
region_screenshot = pyautogui.screenshot(region=(100, 100, 300, 200))
region_screenshot.save("region_screen.png")
3. 鼠标操作
PyAutoGUI 的坐标系统:屏幕左上角为 (0, 0),向右 x 递增,向下 y 递增。
(1)移动鼠标
# 绝对移动:移到屏幕(500, 500)位置,耗时2秒(平滑移动)
pyautogui.moveTo(500, 500, duration=2)
# 相对移动:从当前位置向右移100像素,向下移50像素,耗时1秒
pyautogui.moveRel(100, 50, duration=1)
(2)点击鼠标
# 左键单击(默认):在(500, 500)位置点击
pyautogui.click(500, 500)
# 右键单击
pyautogui.rightClick(500, 500)
# 双击左键
pyautogui.doubleClick(500, 500)
# 左键按住再释放(拖拽基础)
pyautogui.mouseDown(500, 500) # 按住
pyautogui.mouseUp(800, 800) # 释放(移到800,800)
(3)拖拽鼠标
# 从(100,100)拖拽到(400,400),耗时2秒
pyautogui.dragTo(400, 400, duration=2)
# 相对拖拽:从当前位置向右拖200像素,向上拖100像素
pyautogui.dragRel(200, -100, duration=1)
(4)滚动鼠标
# 滚动鼠标滚轮(正数向上,负数向下),在(500,500)位置滚动
pyautogui.scroll(10, x=500, y=500) # 向上滚10格
pyautogui.scroll(-10, x=500, y=500) # 向下滚10格
4. 键盘操作
(1)输入文字
# 直接输入文字(支持英文,中文需确保输入法匹配)
pyautogui.typewrite("Hello PyAutoGUI!")
# 逐字符输入,间隔0.2秒(模拟人工输入)
pyautogui.typewrite("Hello World", interval=0.2)
(2)单键操作
# 按下并释放单个按键(如回车、空格)
pyautogui.press("enter") # 按回车键
pyautogui.press("space") # 按空格键
pyautogui.press("esc") # 按ESC键
# 按住按键 → 释放按键(组合键基础)
pyautogui.keyDown("shift") # 按住shift
pyautogui.keyUp("shift") # 释放shift
(3)组合键操作
# 快捷键:Ctrl+C(复制)
pyautogui.hotkey("ctrl", "c")
# 快捷键:Ctrl+V(粘贴)
pyautogui.hotkey("ctrl", "v")
# 快捷键:Alt+F4(关闭窗口,Windows)
pyautogui.hotkey("alt", "f4")
5. 图像定位(精准操作)
通过截图匹配屏幕上的目标位置,返回坐标:
# 定位屏幕上的目标图片(需提前保存目标截图,如button.png)
# 返回值:(x, y, 宽度, 高度),若未找到返回None
target_pos = pyautogui.locateOnScreen("button.png")
if target_pos:
# 获取目标图片的中心坐标
center_x, center_y = pyautogui.center(target_pos)
# 点击目标中心
pyautogui.click(center_x, center_y)
else:
print("未找到目标图片")
# 可选参数:提高匹配容错率(grayscale=True 灰度匹配,confidence=0.8 置信度)
target_pos = pyautogui.locateOnScreen("button.png", grayscale=True, confidence=0.8)
注意:图像定位需确保截图与屏幕显示一致(分辨率、缩放比例),否则匹配失败。
三、完整示例:自动打开记事本并输入文字
import pyautogui
import time
# 基础配置
pyautogui.FAILSAFE = True
pyautogui.PAUSE = 1
# 1. 打开Windows开始菜单(按Win键)
pyautogui.press("win")
# 2. 输入"记事本"并回车
pyautogui.typewrite("记事本")
pyautogui.press("enter")
# 3. 等待记事本打开(额外延时,确保窗口加载)
time.sleep(2)
# 4. 在记事本中输入文字
pyautogui.typewrite("Hello PyAutoGUI!\n这是自动化输入的内容~", interval=0.1)
# 5. 保存文件(Ctrl+S)
pyautogui.hotkey("ctrl", "s")
# 6. 输入文件名并保存
pyautogui.typewrite("自动化测试.txt")
pyautogui.press("enter")
四、注意事项
- 防止失控:开启
FAILSAFE = True,操作失控时快速将鼠标移到屏幕左上角终止程序。 - 权限问题:macOS/Linux 需开启对应权限,否则无法模拟操作。
- 中文输入:PyAutoGUI 直接
typewrite中文可能乱码,建议先切换到中文输入法,或使用剪贴板 + 粘贴(pyperclip库配合hotkey("ctrl","v"))。 - 调试技巧:先通过
pyautogui.position()打印当前鼠标坐标,确定目标位置后再写代码。
五、常见问题
- 安装失败:升级 pip(
pip install --upgrade pip),或检查 Python 环境是否正常。 - 操作无响应:检查系统权限(macOS/Linux)、坐标是否正确、目标窗口是否在前台。
- 图像定位失败:确保截图清晰、分辨率匹配,添加
confidence参数降低匹配精度。
vauto input
初级
import pyautogui
import time
import random # 导入random模块用于生成随机延迟
# 您的代码内容,用三引号字符串保存
code_to_type = """
<template>
"""
# 确保有足够的时间将光标切换到您指定的文件或输入框
print("准备开始输入,请确保光标已在目标位置...")
time.sleep(5) # 给您5秒时间切换窗口
# ========== 解决搜狗输入法自动切换中文的问题 ==========
print("正在切换到英文输入法...")
pyautogui.hotkey('ctrl', 'space') # 切换到英文输入法
time.sleep(0.5) # 等待切换完成
# ===================================================
print("开始输入代码...")
# 初始化变量
line_count = 0 # 行计数器
threshold = random.randint(5, 30) # 随机阈值,5-30行之间
print(f"当前阈值:每 {threshold} 行后切换延迟范围")
# 逐行逐字符输入
for line in code_to_type.splitlines():
# 为当前行的每个字符生成随机延迟
for char in line:
# 为每个字符生成0.1到2.0秒之间的随机延迟
delay_between_chars = random.uniform(0.1, 2.0)
pyautogui.write(char, interval=delay_between_chars)
# 行计数器加1
line_count += 1
# 检查是否达到阈值
if line_count >= threshold:
# 达到阈值,使用长延迟范围:6.0-20.0秒
delay_between_lines = random.uniform(6.0, 20.0)
print(f"第 {line_count} 行:达到阈值,使用长延迟范围 (6.0-20.0秒)")
# 重置计数器和生成新的随机阈值
line_count = 0
threshold = random.randint(5, 30)
print(f"重置阈值:每 {threshold} 行后切换延迟范围")
else:
# 未达到阈值,使用正常延迟范围:1.5-5.0秒
delay_between_lines = random.uniform(1.5, 5.0)
print(f"第 {line_count} 行:正常延迟范围 (1.5-5.0秒),距离阈值还有 {threshold - line_count} 行")
pyautogui.press('enter') # 输入完一行后按回车
time.sleep(delay_between_lines)
print("代码输入完成!")
人工
import pyautogui
import time
import random
import math
import json
from datetime import datetime
import os
from enum import Enum
# ========== 配置参数 ==========
code_to_type = """
print("ok")
print("ok")
"""
# ========== 枚举定义 ==========
class ProgrammerType(Enum):
"""程序员类型枚举"""
BEGINNER = "beginner" # 新手:慢速,多错误,频繁查看参考
INTERMEDIATE = "intermediate" # 中级:中等速度,偶尔错误
EXPERT = "expert" # 专家:快速,少错误,流畅
TIRED = "tired" # 疲劳状态:慢速,易错,分心
FOCUSED = "focused" # 专注状态:快速,准确
DISTRACTED = "distracted" # 分心状态:频繁中断
class ErrorType(Enum):
"""错误类型枚举"""
TYPO = "typo" # 拼写错误
CASE = "case" # 大小写错误
EXTRA = "extra" # 多余字符
MISSING = "missing" # 缺失字符
ORDER = "order" # 顺序错误
SYNTAX = "syntax" # 语法错误
# ========== 认知模型模拟器 ==========
class CognitiveModelSimulator:
"""模拟人类打字的认知模型(基于研究论文)"""
def __init__(self):
# 四个认知代理的状态
self.supervisor_active = True # 监督控制:决定注意力分配
self.guide_active = True # 引导:控制手指运动
self.vision_active = True # 视觉:处理视觉信息
self.proofread_active = False # 校对:检查错误
# 视觉注意力参数
self.gaze_keyboard_ratio = 0.3 # 看键盘的时间比例
self.gaze_code_ratio = 0.7 # 看代码的时间比例
self.fixation_duration = 0.2 # 注视持续时间(秒)
# 错误检测延迟
self.error_detection_delay_min = 0.5 # 最小检测延迟
self.error_detection_delay_max = 3.0 # 最大检测延迟
# 当前状态
self.current_gaze_target = "code" # 当前注视目标:code/keyboard
self.last_gaze_switch = time.time()
self.pending_errors = [] # 待检测的错误
def simulate_gaze_switch(self):
"""模拟视觉注意力切换"""
if random.random() < 0.1: # 10%概率切换注视目标
if self.current_gaze_target == "code":
self.current_gaze_target = "keyboard"
# 模拟看键盘的时间
gaze_time = random.uniform(0.1, 0.5)
time.sleep(gaze_time)
print(f" 👀 视线切换到键盘 ({gaze_time:.1f}s)")
else:
self.current_gaze_target = "code"
# 模拟看代码的时间
gaze_time = random.uniform(0.2, 1.0)
time.sleep(gaze_time)
print(f" 👀 视线切换到代码 ({gaze_time:.1f}s)")
self.last_gaze_switch = time.time()
return True
return False
def schedule_error_detection(self, error_info):
"""安排错误检测(人类不会立即发现错误)"""
detection_delay = random.uniform(
self.error_detection_delay_min,
self.error_detection_delay_max
)
error_info['detection_time'] = time.time() + detection_delay
self.pending_errors.append(error_info)
def check_pending_errors(self):
"""检查是否有错误需要检测"""
current_time = time.time()
errors_to_detect = []
for error in self.pending_errors[:]:
if current_time >= error['detection_time']:
errors_to_detect.append(error)
self.pending_errors.remove(error)
return errors_to_detect
# ========== 个性化配置文件 ==========
class PersonalityProfile:
"""程序员个性化配置文件"""
def __init__(self, programmer_type=ProgrammerType.INTERMEDIATE):
self.type = programmer_type
self.habitual_errors = [] # 习惯性错误模式
self.preferred_patterns = [] # 偏好模式
self.learning_curve = 0.0 # 学习曲线(0-1)
self.fatigue_level = 0.0 # 疲劳程度(0-1)
# 根据类型设置基础参数
self.setup_by_type()
# 修复:初始化有效参数
self.effective_speed = self.base_speed
self.effective_error_rate = self.error_rate
def setup_by_type(self):
"""根据程序员类型设置参数"""
if self.type == ProgrammerType.BEGINNER:
self.base_speed = 0.3 # 慢速
self.error_rate = 0.15 # 高错误率
self.thinking_time = 2.0 # 长思考时间
self.reference_freq = 0.2 # 频繁查看参考
self.distraction_freq = 0.1 # 较少分心(专注学习)
elif self.type == ProgrammerType.INTERMEDIATE:
self.base_speed = 0.7 # 中速
self.error_rate = 0.08 # 中等错误率
self.thinking_time = 1.0 # 中等思考时间
self.reference_freq = 0.08 # 偶尔查看参考
self.distraction_freq = 0.15 # 中等分心
elif self.type == ProgrammerType.EXPERT:
self.base_speed = 1.2 # 快速
self.error_rate = 0.03 # 低错误率
self.thinking_time = 0.3 # 短思考时间
self.reference_freq = 0.02 # 很少查看参考
self.distraction_freq = 0.05 # 很少分心
elif self.type == ProgrammerType.TIRED:
self.base_speed = 0.4 # 慢速
self.error_rate = 0.12 # 较高错误率
self.thinking_time = 1.5 # 长思考时间
self.reference_freq = 0.05 # 较少查看参考
self.distraction_freq = 0.25 # 易分心
elif self.type == ProgrammerType.FOCUSED:
self.base_speed = 1.0 # 快速
self.error_rate = 0.04 # 低错误率
self.thinking_time = 0.5 # 短思考时间
self.reference_freq = 0.03 # 很少查看参考
self.distraction_freq = 0.02 # 几乎不分心
else: # DISTRACTED
self.base_speed = 0.5 # 中慢速
self.error_rate = 0.1 # 较高错误率
self.thinking_time = 0.8 # 中等思考时间
self.reference_freq = 0.1 # 经常查看参考
self.distraction_freq = 0.3 # 频繁分心
def update_fatigue(self, elapsed_time):
"""更新疲劳程度"""
# 随时间增加疲劳
self.fatigue_level = min(1.0, elapsed_time / 3600) # 1小时后达到最大疲劳
# 疲劳影响参数
fatigue_factor = 1.0 + self.fatigue_level * 0.5
self.effective_speed = self.base_speed / fatigue_factor
self.effective_error_rate = self.error_rate * fatigue_factor
def update_learning(self, lines_typed):
"""更新学习曲线"""
# 每输入100行,学习曲线增加0.1
self.learning_curve = min(1.0, lines_typed / 1000)
# 学习影响参数
learning_factor = 1.0 - self.learning_curve * 0.3
self.effective_error_rate = self.error_rate * learning_factor
# ========== 上下文感知引擎 ==========
class ContextAwareEngine:
"""代码上下文感知引擎"""
def __init__(self):
self.code_language = self.detect_language()
self.current_context = "global"
self.context_stack = [] # 上下文栈
self.indent_level = 0
self.brace_balance = 0
self.parenthesis_balance = 0
# 常见模式库
self.common_patterns = {
'html': ['<div>', '</div>', '<span>', '</span>', 'class="', 'id="'],
'python': ['def ', 'class ', 'if ', 'for ', 'while ', 'import '],
'javascript': ['function ', 'const ', 'let ', '=>', 'console.log'],
'java': ['public ', 'private ', 'class ', 'void ', 'System.out.println'],
'cpp': ['#include', 'using namespace', 'cout <<', 'cin >>']
}
def detect_language(self):
"""检测代码语言"""
code_sample = code_to_type[:500].lower()
if '<template>' in code_sample or '<div>' in code_sample:
return 'html'
elif 'import ' in code_sample and ('from ' in code_sample or 'as ' in code_sample):
return 'python'
elif 'function ' in code_sample or 'const ' in code_sample or 'let ' in code_sample:
return 'javascript'
elif 'public ' in code_sample or 'class ' in code_sample or 'void ' in code_sample:
return 'java'
elif '#include' in code_sample or 'namespace ' in code_sample:
return 'cpp'
else:
return 'unknown'
def analyze_line(self, line):
"""分析代码行上下文"""
line_stripped = line.strip()
# 更新括号平衡
self.brace_balance += line.count('{') - line.count('}')
self.parenthesis_balance += line.count('(') - line.count(')')
# 检测上下文变化
if line_stripped.endswith('{'):
self.context_stack.append(self.current_context)
self.current_context = "block"
self.indent_level += 1
elif line_stripped.startswith('}') or line_stripped == '}':
if self.context_stack:
self.current_context = self.context_stack.pop()
self.indent_level = max(0, self.indent_level - 1)
# 检测特定结构
if any(pattern in line for pattern in self.common_patterns.get(self.code_language, [])):
return "pattern"
elif '//' in line or '#' in line or '/*' in line:
return "comment"
elif not line_stripped:
return "empty"
elif len(line_stripped) < 20:
return "simple"
else:
return "complex"
def get_context_suggestion(self):
"""根据上下文提供建议"""
if self.code_language == 'html' and self.current_context == 'block':
return "考虑闭合标签"
elif self.brace_balance > 0:
return f"需要 {self.brace_balance} 个右大括号"
elif self.parenthesis_balance > 0:
return f"需要 {self.parenthesis_balance} 个右括号"
return None
# ========== 真实错误模式库 ==========
class RealisticErrorLibrary:
"""真实的人类错误模式库"""
def __init__(self):
# 常见拼写错误映射
self.common_typos = {
'the': ['teh', 'hte'],
'function': ['functon', 'fucntion'],
'return': ['retrun', 'reutrn'],
'variable': ['varialbe', 'variabel'],
'console': ['consle', 'conosle'],
'template': ['templat', 'templet'],
'import': ['improt', 'inport'],
'export': ['exprot', 'epxort'],
'default': ['defualt', 'defautl'],
'async': ['asnyc', 'ansyc'],
'await': ['awiat', 'aiwt'],
'const': ['cosnt', 'conts'],
'let': ['elt', 'lte'],
'var': ['vra', 'arv']
}
# 语法错误模式
self.syntax_errors = [
(';', ''), # 缺少分号
('(', ')'), # 括号不匹配
('{', '}'), # 大括号不匹配
('[', ']'), # 方括号不匹配
('=', '=='), # 赋值 vs 比较
('==', '='), # 比较 vs 赋值
('&&', '&'), # 逻辑与 vs 位与
('||', '|'), # 逻辑或 vs 位或
]
# 习惯性错误(个人特有)
self.habitual_errors = [
'i' # 经常忘记大写 I
]
def generate_realistic_error(self, word, context):
"""生成真实的错误"""
if word.lower() in self.common_typos:
if random.random() < 0.3: # 30%概率犯常见错误
return random.choice(self.common_typos[word.lower()])
# 大小写错误
if word and word[0].isalpha():
if random.random() < 0.1: # 10%概率大小写错误
if word[0].islower():
return word[0].upper() + word[1:]
else:
return word[0].lower() + word[1:]
# 顺序错误(交换相邻字符)
if len(word) > 2 and random.random() < 0.05:
idx = random.randint(0, len(word) - 2)
chars = list(word)
chars[idx], chars[idx + 1] = chars[idx + 1], chars[idx]
return ''.join(chars)
return None
# ========== 动态参数管理器(增强版) ==========
class EnhancedDynamicParamManager:
def __init__(self, personality_profile):
self.personality = personality_profile
self.param_history = []
self.current_params = {}
self.switch_countdown = random.randint(8, 15) # 更频繁的切换
self.mood_state = "neutral" # 情绪状态
self.initialize_params()
def initialize_params(self):
"""基于个性化初始化参数"""
# 基础行为概率
self.current_params = {
'ERROR_PROBABILITY': self.personality.effective_error_rate,
'THINKING_PROBABILITY': 0.3 * (2.0 - self.personality.effective_speed),
'CURSOR_MOVE_PROBABILITY': 0.02,
'SCROLL_PROBABILITY': 0.03 * self.personality.distraction_freq,
'SPEED_CHANGE_PROBABILITY': 0.1,
'COPY_PASTE_PROBABILITY': 0.04,
'COMMENT_PROBABILITY': 0.08,
'DEBUG_PROBABILITY': 0.02,
'ENV_SWITCH_PROBABILITY': 0.06 * self.personality.distraction_freq,
'AUTOCOMPLETE_PROBABILITY': 0.15,
'REFERENCE_VIEW_PROBABILITY': self.personality.reference_freq,
'DISTRACTION_PROBABILITY': self.personality.distraction_freq,
'CODE_REVIEW_PROBABILITY': 0.07,
'TEST_RUN_PROBABILITY': 0.03,
'GAZE_SWITCH_PROBABILITY': 0.1, # 视线切换概率
'PATTERN_RECOGNITION_PROBABILITY': 0.2, # 模式识别概率
'CONTEXT_AWARE_ADJUSTMENT_PROBABILITY': 0.25 # 上下文调整概率
}
# 情绪影响
self.apply_mood_effects()
def apply_mood_effects(self):
"""应用情绪状态影响"""
mood_effects = {
"frustrated": {"ERROR_PROBABILITY": 1.5, "THINKING_PROBABILITY": 1.3},
"confident": {"ERROR_PROBABILITY": 0.7, "SPEED_CHANGE_PROBABILITY": 1.2},
"tired": {"ERROR_PROBABILITY": 1.4, "DISTRACTION_PROBABILITY": 1.5},
"focused": {"ERROR_PROBABILITY": 0.8, "DISTRACTION_PROBABILITY": 0.5},
"rushed": {"ERROR_PROBABILITY": 1.6, "THINKING_PROBABILITY": 0.7}
}
if self.mood_state in mood_effects:
for param, factor in mood_effects[self.mood_state].items():
if param in self.current_params:
self.current_params[param] *= factor
def update_mood(self, recent_errors, recent_speed):
"""根据近期表现更新情绪"""
if recent_errors > 3: # 错误太多
self.mood_state = "frustrated"
elif recent_speed > self.personality.base_speed * 1.2: # 速度很快
self.mood_state = "confident"
elif recent_speed < self.personality.base_speed * 0.7: # 速度很慢
self.mood_state = "tired"
else:
self.mood_state = random.choice(["neutral", "focused", "rushed"])
self.apply_mood_effects()
print(f" 😊 情绪状态: {self.mood_state}")
def update_params(self, line_num, context_analysis):
"""更新参数(每行调用)"""
self.switch_countdown -= 1
# 定期随机切换
if self.switch_countdown <= 0:
self.random_switch_all_params()
self.switch_countdown = random.randint(8, 15)
print(f" 🔄 参数随机切换 (下次: {self.switch_countdown}行后)")
# 上下文调整
if random.random() < self.current_params['CONTEXT_AWARE_ADJUSTMENT_PROBABILITY']:
self.adjust_for_context(context_analysis)
def random_switch_all_params(self):
"""随机切换所有参数"""
old_params = self.current_params.copy()
for key in self.current_params.keys():
# 随机变化 ±30%
change = random.uniform(-0.3, 0.3)
new_value = self.current_params[key] * (1 + change)
# 保持在合理范围
self.current_params[key] = max(0.01, min(0.5, new_value))
self.param_history.append({
'timestamp': datetime.now().isoformat(),
'old': old_params,
'new': self.current_params.copy()
})
def adjust_for_context(self, context):
"""根据上下文调整参数"""
context_adjustments = {
"complex": {"THINKING_PROBABILITY": 1.5, "ERROR_PROBABILITY": 1.3},
"simple": {"THINKING_PROBABILITY": 0.7, "ERROR_PROBABILITY": 0.8},
"pattern": {"AUTOCOMPLETE_PROBABILITY": 1.4, "ERROR_PROBABILITY": 0.6},
"comment": {"THINKING_PROBABILITY": 0.5, "SPEED_CHANGE_PROBABILITY": 1.2},
"empty": {"SPEED_CHANGE_PROBABILITY": 1.5}
}
if context in context_adjustments:
for param, factor in context_adjustments[context].items():
if param in self.current_params:
self.current_params[param] *= factor
# ========== 主程序 ==========
def main():
print("=" * 70)
print("🤖 超真实人类代码输入模拟器 v3.0")
print("=" * 70)
# 选择程序员类型
print("\n👤 选择程序员类型:")
for i, ptype in enumerate(ProgrammerType, 1):
print(f" {i}. {ptype.value}")
try:
choice = int(input("请输入编号 (1-6, 默认2): ") or "2")
programmer_type = list(ProgrammerType)[choice - 1]
except:
programmer_type = ProgrammerType.INTERMEDIATE
print(f"\n🎭 模拟: {programmer_type.value} 程序员")
# 初始化所有组件
lines = code_to_type.splitlines()
total_lines = len(lines)
personality = PersonalityProfile(programmer_type)
context_engine = ContextAwareEngine()
error_library = RealisticErrorLibrary()
param_manager = EnhancedDynamicParamManager(personality)
cognitive_model = CognitiveModelSimulator()
print(f"📝 检测到代码语言: {context_engine.code_language}")
print(f"📊 总行数: {total_lines}")
print("⏳ 准备开始输入 (5秒后开始)...")
time.sleep(5)
# 切换到英文输入法
pyautogui.hotkey('ctrl', 'space')
time.sleep(0.5)
print("\n🚀 开始模拟人类代码输入...\n")
# 统计变量
start_time = time.time()
total_errors = 0
recent_error_count = [] # 修复:改为列表存储每行的错误数
recent_speed_samples = []
line_timings = []
# 主输入循环
for line_index, line in enumerate(lines):
line_num = line_index + 1
line_start_time = time.time()
# 显示进度
progress = (line_num / total_lines) * 100
elapsed = time.time() - start_time
if line_num > 1:
avg_time_per_line = elapsed / (line_num - 1)
eta = (total_lines - line_num) * avg_time_per_line
eta_str = f"{eta/60:.1f}分钟"
else:
eta_str = "计算中..."
print(f"[{line_num:3d}/{total_lines}] 进度: {progress:5.1f}% | ETA: {eta_str}")
print(f" 代码: {line[:50]}..." if len(line) > 50 else f" 代码: {line}")
# 1. 更新个性化状态
personality.update_fatigue(elapsed)
personality.update_learning(line_num)
# 2. 分析上下文
context = context_engine.analyze_line(line)
context_suggestion = context_engine.get_context_suggestion()
if context_suggestion:
print(f" 💡 上下文提示: {context_suggestion}")
# 3. 更新参数和情绪
param_manager.update_params(line_num, context)
if line_num % 5 == 0: # 每5行更新一次情绪
# 修复:计算最近错误总数
recent_errors_total = sum(recent_error_count[-5:]) if recent_error_count else 0
recent_speed_avg = sum(recent_speed_samples[-5:])/5 if recent_speed_samples else personality.base_speed
param_manager.update_mood(recent_errors_total, recent_speed_avg)
# 4. 模拟认知过程
cognitive_model.simulate_gaze_switch()
# 5. 检查待检测的错误
pending_errors = cognitive_model.check_pending_errors()
for error in pending_errors:
print(f" 🔍 检测到错误: {error['type']} -> {error['original']}")
# 模拟纠正错误
time.sleep(random.uniform(0.3, 1.0))
for _ in range(len(error['original'])):
pyautogui.press('backspace')
time.sleep(0.05)
pyautogui.write(error['corrected'], interval=0.1)
total_errors += 1
# 6. 逐词输入(更真实)
words = line.split(' ')
line_errors = 0 # 本行错误计数
for word_index, word in enumerate(words):
# 词间空格(除了最后一个词)
if word_index > 0:
pyautogui.write(' ', interval=random.uniform(0.05, 0.2))
# 检查是否应该犯错误
should_error = random.random() < param_manager.current_params['ERROR_PROBABILITY']
if should_error and word:
# 生成真实错误
erroneous_word = error_library.generate_realistic_error(word, context)
if erroneous_word:
print(f" ❌ 输入错误: '{word}' -> '{erroneous_word}'")
# 输入错误版本
pyautogui.write(erroneous_word, interval=random.uniform(0.1, 0.3))
# 安排错误检测(不会立即发现)
cognitive_model.schedule_error_detection({
'type': 'typo',
'original': erroneous_word,
'corrected': word,
'position': (line_num, word_index)
})
line_errors += 1
continue
# 正常输入
char_delay = random.uniform(
0.1 / personality.effective_speed,
0.5 / personality.effective_speed
)
# 模拟思考(在特定字符后)
if word and any(c in word for c in [';', '{', '}', '(', ')']):
if random.random() < param_manager.current_params['THINKING_PROBABILITY']:
think_time = random.uniform(0.5, personality.thinking_time)
time.sleep(think_time)
print(f" 🤔 思考中 ({think_time:.1f}s)")
pyautogui.write(word, interval=char_delay)
# 记录本行错误数
recent_error_count.append(line_errors)
# 7. 行后行为
line_end_time = time.time()
line_duration = line_end_time - line_start_time
line_timings.append(line_duration)
recent_speed_samples.append(len(line) / line_duration if line_duration > 0 else 0)
# 保持最近10个样本
if len(recent_speed_samples) > 10:
recent_speed_samples.pop(0)
if len(recent_error_count) > 10:
recent_error_count.pop(0)
# 行间延迟(基于上下文和疲劳)
base_line_delay = random.uniform(0.5, 2.0) / personality.effective_speed
if context == "complex":
base_line_delay *= 1.5
elif context == "simple":
base_line_delay *= 0.7
# 疲劳增加延迟
base_line_delay *= (1 + personality.fatigue_level * 0.3)
print(f" ⏱️ 本行耗时: {line_duration:.1f}s | 延迟: {base_line_delay:.1f}s")
pyautogui.press('enter')
time.sleep(base_line_delay)
# 完成统计
total_time = time.time() - start_time
avg_chars_per_second = sum(len(line) for line in lines) / total_time
print("\n" + "=" * 70)
print("🎉 模拟完成!")
print("=" * 70)
print(f"\n📈 性能统计:")
print(f" 总时间: {total_time/60:.1f}分钟")
print(f" 总行数: {total_lines}")
print(f" 总错误: {total_errors}")
print(f" 平均速度: {avg_chars_per_second:.1f} 字符/秒")
print(f" 平均每行: {total_time/total_lines:.1f}秒")
print(f" 疲劳程度: {personality.fatigue_level:.2f}")
print(f" 学习曲线: {personality.learning_curve:.2f}")
print(f"\n🎭 模拟配置:")
print(f" 程序员类型: {programmer_type.value}")
print(f" 代码语言: {context_engine.code_language}")
print(f" 最终情绪: {param_manager.mood_state}")
print(f"\n💾 数据已保存到: simulation_report.json")
# 保存报告
report = {
'timestamp': datetime.now().isoformat(),
'programmer_type': programmer_type.value,
'code_language': context_engine.code_language,
'total_lines': total_lines,
'total_time_seconds': total_time,
'total_errors': total_errors,
'avg_speed_chars_per_sec': avg_chars_per_second,
'fatigue_level': personality.fatigue_level,
'learning_curve': personality.learning_curve,
'final_mood': param_manager.mood_state,
'line_timings': line_timings,
'param_history': param_manager.param_history
}
with open('simulation_report.json', 'w', encoding='utf-8') as f:
json.dump(report, f, indent=2, ensure_ascii=False)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\n\n⚠️ 模拟被用户中断")
except Exception as e:
print(f"\n❌ 模拟错误: {e}")
import traceback
traceback.print_exc()
v源码地址
https://github.com/toutouge/javademosecond
作 者:请叫我头头哥
出 处:http://www.cnblogs.com/toutou/
关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角**【推荐】** 一下。您的鼓励是作者坚持原创和持续写作的最大动力!