import random import asyncio from typing import Optional class PasteTypingSimulator: """模拟用户复制粘贴行为的输入模拟器""" def __init__(self, page=None): self.page = page self.config = { 'pre_paste_delay': (0.5, 1.2), # 粘贴前的停顿时间 'post_paste_delay': (0.8, 1.5), # 粘贴后的停顿时间 'review_probability': 0.7, # 检查内容的概率 'review_time': (1.5, 3.0), # 检查内容的时间 'adjust_probability': 0.4, # 调整格式的概率 'adjust_delay': (0.3, 0.8), # 调整时的停顿 'scroll_probability': 0.6, # 滚动查看的概率 'scroll_delay': (0.5, 1.0), # 滚动时的停顿 } async def paste_text(self, text: str, selector: str = None) -> bool: """模拟用户粘贴文本的行为""" try: if selector: # 找到目标输入框并聚焦 element = await self.page.wait_for_selector(selector) await element.click() await asyncio.sleep(random.uniform(0.2, 0.4)) # 全选当前内容(如果有的话) await self.page.keyboard.press("Control+A") await asyncio.sleep(random.uniform(0.1, 0.2)) # 模拟快速输入(类似粘贴的效果) await self.page.keyboard.type(text, delay=10) # 使用很小的延迟来模拟粘贴的快速输入 # 模拟粘贴后的检查动作 await self._post_paste_actions() return True except Exception as e: print(f"粘贴文本时出错: {e}") return False async def _prepare_input(self, selector: str): """准备输入区域""" try: # 等待元素出现并点击 element = await self.page.wait_for_selector(selector, timeout=5000) await element.click() # 模拟点击后的短暂停顿 await asyncio.sleep(random.uniform(0.3, 0.6)) # 清空现有内容 await self.page.keyboard.press("Control+A") await asyncio.sleep(random.uniform(0.1, 0.2)) await self.page.keyboard.press("Delete") await asyncio.sleep(random.uniform(0.2, 0.4)) except Exception as e: print(f"准备输入区域失败: {e}") raise async def _pre_paste_actions(self): """模拟粘贴前的准备动作""" # 模拟思考和准备时间 await asyncio.sleep(random.uniform(*self.config['pre_paste_delay'])) # 模拟按下 Ctrl 键 await self.page.keyboard.down("Control") await asyncio.sleep(random.uniform(0.05, 0.1)) # 模拟按下 V 键 await self.page.keyboard.press("v") await asyncio.sleep(random.uniform(0.05, 0.1)) # 释放 Ctrl 键 await self.page.keyboard.up("Control") async def _perform_paste(self): """执行粘贴操作""" # 等待内容出现 await asyncio.sleep(random.uniform(0.3, 0.5)) async def _post_paste_actions(self): """模拟粘贴后的检查和调整动作""" # 模拟粘贴后的停顿 await asyncio.sleep(random.uniform(*self.config['post_paste_delay'])) # 随机检查内容 if random.random() < self.config['review_probability']: # 模拟上下滚动查看内容 if random.random() < self.config['scroll_probability']: # 向下滚动 await self.page.keyboard.press("PageDown") await asyncio.sleep(random.uniform(*self.config['scroll_delay'])) # 向上滚动 await self.page.keyboard.press("PageUp") await asyncio.sleep(random.uniform(*self.config['scroll_delay'])) # 模拟检查时间 await asyncio.sleep(random.uniform(*self.config['review_time'])) # 随机调整格式 if random.random() < self.config['adjust_probability']: # 模拟删除多余空行 for _ in range(random.randint(1, 2)): await self.page.keyboard.press("End") await asyncio.sleep(random.uniform(0.1, 0.2)) await self.page.keyboard.press("Backspace") await asyncio.sleep(random.uniform(*self.config['adjust_delay'])) async def paste_with_format_check(self, text: str, selector: str = None) -> bool: """带格式检查的粘贴方法""" try: # 模拟复制文本到剪贴板 await self.page.evaluate(f'navigator.clipboard.writeText(`{text}`)') await asyncio.sleep(random.uniform(*self.config['pre_paste_delay'])) if selector: await self._prepare_input(selector) # 模拟粘贴操作 await self.page.keyboard.down("Control") await asyncio.sleep(random.uniform(0.05, 0.1)) await self.page.keyboard.press("v") await asyncio.sleep(random.uniform(0.05, 0.1)) await self.page.keyboard.up("Control") # 模拟粘贴后的检查 await asyncio.sleep(random.uniform(*self.config['post_paste_delay'])) # 随机检查内容 if random.random() < self.config['review_probability']: await asyncio.sleep(random.uniform(*self.config['review_time'])) return True except Exception as e: print(f"格式检查粘贴失败: {e}") return False