143 lines
5.8 KiB
Python
143 lines
5.8 KiB
Python
|
|
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
|