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)# 行计数器加1line_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 = 0threshold = 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/keyboardself.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 Truereturn Falsedef 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_delayself.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_typeself.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_speedself.effective_error_rate = self.error_ratedef 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: # DISTRACTEDself.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.5self.effective_speed = self.base_speed / fatigue_factorself.effective_error_rate = self.error_rate * fatigue_factordef update_learning(self, lines_typed):"""更新学习曲线"""# 每输入100行,学习曲线增加0.1self.learning_curve = min(1.0, lines_typed / 1000)# 学习影响参数learning_factor = 1.0 - self.learning_curve * 0.3self.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 = 0self.brace_balance = 0self.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 += 1elif 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_profileself.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] *= factordef 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.INTERMEDIATEprint(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 = 0recent_error_count = [] # 修复:改为列表存储每行的错误数recent_speed_samples = []line_timings = []# 主输入循环for line_index, line in enumerate(lines):line_num = line_index + 1line_start_time = time.time()# 显示进度progress = (line_num / total_lines) * 100elapsed = time.time() - start_timeif line_num > 1:avg_time_per_line = elapsed / (line_num - 1)eta = (total_lines - line_num) * avg_time_per_lineeta_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 0recent_speed_avg = sum(recent_speed_samples[-5:])/5 if recent_speed_samples else personality.base_speedparam_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 += 1continue# 正常输入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_timeline_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_speedif context == "complex":base_line_delay *= 1.5elif 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_timeavg_chars_per_second = sum(len(line) for line in lines) / total_timeprint("\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 tracebacktraceback.print_exc()
v源码地址
https://github.com/toutouge/javademosecond
作 者:请叫我头头哥
出 处:http://www.cnblogs.com/toutou/
关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!
