78 lines
2.9 KiB
Python
78 lines
2.9 KiB
Python
import time
|
|
import random
|
|
from playwright.sync_api import Page
|
|
|
|
class HumanLikeTyper:
|
|
"""模拟人类输入文本的工具类"""
|
|
|
|
def __init__(self, page: Page):
|
|
self.page = page
|
|
# 定义人类输入速度范围(字符/秒)
|
|
self.min_typing_speed = 3
|
|
self.max_typing_speed = 8
|
|
# 定义思考停顿概率和时长范围
|
|
self.pause_probability = 0.1 # 10%的概率停顿
|
|
self.min_pause_duration = 0.5
|
|
self.max_pause_duration = 2.0
|
|
# 定义错误修正概率
|
|
self.correction_probability = 0.08 # 8%的概率出现错误并修正
|
|
|
|
def _calculate_typing_delay(self):
|
|
"""计算每个字符之间的延迟时间(秒)"""
|
|
speed = random.uniform(self.min_typing_speed, self.max_typing_speed)
|
|
return 1 / speed + random.uniform(-0.05, 0.1) # 添加随机波动
|
|
|
|
def _maybe_pause(self):
|
|
"""随机停顿,模拟思考过程"""
|
|
if random.random() < self.pause_probability:
|
|
pause_time = random.uniform(self.min_pause_duration, self.max_pause_duration)
|
|
time.sleep(pause_time)
|
|
|
|
def _maybe_correct(self, current_text: str, target_char: str):
|
|
"""随机模拟输入错误并修正"""
|
|
if random.random() < self.correction_probability and current_text:
|
|
# 删除最后一个字符
|
|
self.page.keyboard.press("Backspace")
|
|
time.sleep(random.uniform(0.1, 0.3))
|
|
|
|
# 随机输入一个错误字符
|
|
wrong_char = random.choice("abcdefghijklmnopqrstuvwxyz ")
|
|
self.page.keyboard.type(wrong_char, delay=random.uniform(50, 150))
|
|
time.sleep(random.uniform(0.1, 0.3))
|
|
|
|
# 删除错误字符
|
|
self.page.keyboard.press("Backspace")
|
|
time.sleep(random.uniform(0.1, 0.3))
|
|
|
|
return True
|
|
return False
|
|
|
|
def type_text(self, selector: str, text: str):
|
|
"""在指定元素中以类人方式输入文本"""
|
|
# 聚焦到输入框
|
|
self.page.wait_for_selector(selector)
|
|
self.page.click(selector)
|
|
time.sleep(random.uniform(0.2, 0.5)) # 点击后停顿一下
|
|
|
|
current_input = ""
|
|
|
|
for char in text:
|
|
# 随机停顿
|
|
self._maybe_pause()
|
|
|
|
# 随机错误修正
|
|
if current_input: # 至少有一个字符才能修正
|
|
self._maybe_correct(current_input, char)
|
|
|
|
# 计算延迟并输入字符
|
|
delay = self._calculate_typing_delay()
|
|
self.page.keyboard.type(char, delay=delay * 1000) # Playwright的delay单位是毫秒
|
|
|
|
current_input += char
|
|
time.sleep(random.uniform(0.01, 0.05)) # 微小停顿
|
|
|
|
# 输入完成后可能再停顿一下
|
|
if random.random() < 0.3:
|
|
time.sleep(random.uniform(0.3, 1.0))
|
|
|
|
|