Python GUI自动化神器PyAutoGUI

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")

四、注意事项

  1. 防止失控:开启 FAILSAFE = True,操作失控时快速将鼠标移到屏幕左上角终止程序。
  2. 权限问题:macOS/Linux 需开启对应权限,否则无法模拟操作。
  3. 中文输入:PyAutoGUI 直接 typewrite 中文可能乱码,建议先切换到中文输入法,或使用剪贴板 + 粘贴(pyperclip 库配合 hotkey("ctrl","v"))。
  4. 调试技巧:先通过 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/

关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!

版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信

声援博主:如果您觉得文章对您有帮助,可以点击文章右下角**【推荐】** 一下。您的鼓励是作者坚持原创和持续写作的最大动力!