import time import random import re import asyncio from typing import Dict, List, Optional class EnhancedHumanTypingSimulator: def __init__(self, page=None): # 保留原方案的简单配置 self.base_config = { 'min_typing_speed': 5, 'max_typing_speed': 15, 'pause_probability': 0.1, 'chunk_input': True, 'max_chunk_length': 50 } # 新增高级特性配置 self.advanced_config = { # 人类状态模拟 'energy_level': random.uniform(0.7, 1.0), 'typing_proficiency': random.uniform(0.6, 0.9), 'emotion_state': random.uniform(0.8, 1.0), # 错误处理 'base_error_rate': random.uniform(0.02, 0.05), 'error_correction_speed': random.uniform(0.3, 0.8), # 速度控制 'speed_variance': random.uniform(0.1, 0.2), 'burst_speed_probability': 0.1 } self.page = page self.typing_session = { 'start_time': None, 'chars_typed': 0, 'last_break_time': time.time() } async def type_text(self, text: str, selector: str = None) -> bool: """增强版的文本输入方法""" try: if selector: # 等待并点击元素 await self._prepare_input(selector) # 初始化会话 self.typing_session['start_time'] = time.time() # 智能分段 chunks = self._smart_split_text(text) for chunk in chunks: # 获取当前状态 current_state = self._get_current_state() # 输入当前段落 await self._type_chunk(chunk, current_state) # 段落间自然停顿 await self._natural_pause(current_state) return True except Exception as e: print(f"输入文本时出错: {e}") return False def _smart_split_text(self, text: str) -> List[str]: """智能文本分段""" paragraphs = text.split('\n') chunks = [] for para in paragraphs: if len(para) <= self.base_config['max_chunk_length']: if para.strip(): chunks.append(para) continue sentences = re.split(r'([。!?,:;])', para) current_chunk = '' for sent in sentences: if len(current_chunk) + len(sent) < self.base_config['max_chunk_length']: current_chunk += sent else: if current_chunk.strip(): chunks.append(current_chunk) current_chunk = sent if current_chunk.strip(): chunks.append(current_chunk) return chunks def _get_current_state(self) -> Dict: """获取当前输入状态""" typing_duration = time.time() - self.typing_session['start_time'] fatigue = min(typing_duration / 300, 0.7) self.advanced_config['energy_level'] *= (1 - fatigue * 0.1) self.advanced_config['emotion_state'] *= random.uniform(0.98, 1.02) return { 'energy_level': max(0.3, self.advanced_config['energy_level']), 'emotion_state': max(0.4, min(1.0, self.advanced_config['emotion_state'])), 'typing_proficiency': self.advanced_config['typing_proficiency'], 'current_error_rate': self._calculate_error_rate(fatigue) } async def _type_chunk(self, chunk: str, state: Dict): """输入文本块""" for char in chunk: typing_speed = self._calculate_typing_speed(state) if random.random() < state['current_error_rate']: await self._handle_typing_error(char, state) else: await self._type_char(char, typing_speed) self.typing_session['chars_typed'] += 1 await self._micro_pause(state) def _calculate_typing_speed(self, state: Dict) -> float: """计算实时打字速度""" base_speed = random.uniform( self.base_config['min_typing_speed'], self.base_config['max_typing_speed'] ) speed = base_speed * ( 0.7 + state['energy_level'] * 0.3 + state['emotion_state'] * 0.2 + state['typing_proficiency'] * 0.3 ) speed *= random.uniform( 1 - self.advanced_config['speed_variance'], 1 + self.advanced_config['speed_variance'] ) return speed def _calculate_error_rate(self, fatigue: float) -> float: """计算当前错误率""" base_rate = self.advanced_config['base_error_rate'] error_rate = base_rate * (1 + fatigue) error_rate *= random.uniform(0.8, 1.2) return min(error_rate, 0.15) async def _handle_typing_error(self, char: str, state: Dict): """处理打字错误""" error_types = ['typo', 'double_hit', 'delay'] error_type = random.choice(error_types) if error_type == 'typo': wrong_char = self._get_similar_char(char) await self._type_char(wrong_char, self._calculate_typing_speed(state)) await asyncio.sleep(random.uniform(0.2, 0.5)) await self._press_key("Backspace") await self._type_char(char, self._calculate_typing_speed(state)) elif error_type == 'double_hit': await self._type_char(char, self._calculate_typing_speed(state)) await self._type_char(char, self._calculate_typing_speed(state)) await asyncio.sleep(random.uniform(0.1, 0.3)) await self._press_key("Backspace") else: # delay await asyncio.sleep(random.uniform(0.3, 0.8)) await self._type_char(char, self._calculate_typing_speed(state)) async def _natural_pause(self, state: Dict): """自然停顿""" base_pause = random.uniform(0.5, 1.5) if state['energy_level'] < 0.5: base_pause *= 1.3 if state['emotion_state'] < 0.6: base_pause *= 1.2 await asyncio.sleep(base_pause * random.uniform(0.8, 1.2)) async def _micro_pause(self, state: Dict): """字符间的微小停顿""" pause_time = random.uniform(0.05, 0.15) if state['energy_level'] < 0.5: pause_time *= 1.2 await asyncio.sleep(pause_time) def _get_similar_char(self, char: str) -> str: """获取相似字符""" similar_chars = { '的': '地得', '了': '着啦', '和': '与跟', '我': '我我', '是': '市师', '在': '再在', '有': '又有', '都': '都读', '好': '号毫' } return random.choice(similar_chars.get(char, char + char)) async def _prepare_input(self, selector: str): """准备输入""" try: await self.page.wait_for_selector(selector, timeout=5000) await self.page.click(selector) await asyncio.sleep(random.uniform(0.3, 0.8)) except Exception as e: print(f"准备输入失败: {e}") raise async def _type_char(self, char: str, speed: float): """输入单个字符""" try: delay = 1000 / speed # 转换为毫秒 await self.page.keyboard.type(char, delay=delay) except Exception as e: print(f"输入字符失败: {e}") raise async def _press_key(self, key: str): """按键操作""" try: await self.page.keyboard.press(key) except Exception as e: print(f"按键操作失败: {e}") raise