Python GUI自动化神器PyAutoGUI
PyAutoGUI 是 Python 的自动化控制库,可模拟鼠标、键盘操作,支持 Windows/macOS/Linux,安装前需确保已安装 Python(推荐 3.6+)和 pip。
v基础功能
一、PyAutoGUI 安装
1. 基础安装(通用)
# 基础安装(Windows/macOS/Linux 通用) pip install pyautogui # 若系统有多个Python版本,用pip3 pip3 install pyautogui # 国内源加速(推荐) pip install pyautogui -i https://pypi.tuna.tsinghua.edu.cn/simple
2. 不同系统的额外依赖
二、PyAutoGUI 核心使用
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. 鼠标操作
(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")
四、注意事项
五、常见问题
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/
关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!



浙公网安备 33010602011771号