下载地址:http://m.pan38.com/download.php?code=RQEBET 提取码:6666
该实现包含完整的OCR识别和自动化点击功能,支持多种配置选项和文本匹配模式。使用时需要安装Tesseract OCR引擎,可以通过命令行参数或配置文件指定识别区域和点击行为。
import cv2
import numpy as np
import pytesseract
import pyautogui
import time
from PIL import ImageGrab, Image
import re
import argparse
import json
from typing import Dict, List, Tuple, Optional
import sys
import os
class TextAutoClickerConfig:
def init(self, config_path: str = None):
self.default_config = {
'ocr_engine': 'tesseract',
'tesseract_path': r'C:\Program Files\Tesseract-OCR\tesseract.exe',
'tessdata_dir': r'C:\Program Files\Tesseract-OCR\tessdata',
'preprocess': {
'threshold': 150,
'invert': True,
'dilate': True,
'kernel_size': 2
},
'click': {
'delay': 0.5,
'move_duration': 0.2,
'confidence': 0.7
},
'region': None,
'max_attempts': 3,
'scan_interval': 1.0
}
self.config = self.load_config(config_path) if config_path else self.default_config
def load_config(self, path: str) -> Dict:
try:
with open(path, 'r', encoding='utf-8') as f:
return {**self.default_config, **json.load(f)}
except Exception as e:
print(f"加载配置文件失败: {str(e)},使用默认配置")
return self.default_config
class TextAutoClicker:
def init(self, config: TextAutoClickerConfig):
self.config = config
self.running = False
self.last_screenshot = None
self.text_cache = {}
# 初始化OCR引擎
if self.config.config['ocr_engine'] == 'tesseract':
pytesseract.pytesseract.tesseract_cmd = self.config.config['tesseract_path']
self.tessdata_config = f'--tessdata-dir "{self.config.config["tessdata_dir"]}"'
def capture_screen(self, region: Tuple[int, int, int, int] = None) -> np.ndarray:
"""捕获屏幕截图"""
bbox = region or self.config.config['region']
screenshot = ImageGrab.grab(bbox=bbox)
self.last_screenshot = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
return self.last_screenshot
def preprocess_image(self, image: np.ndarray) -> np.ndarray:
"""图像预处理"""
cfg = self.config.config['preprocess']
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 二值化处理
_, binary = cv2.threshold(
gray,
cfg['threshold'],
255,
cv2.THRESH_BINARY_INV if cfg['invert'] else cv2.THRESH_BINARY
)
# 膨胀处理
if cfg['dilate']:
kernel = np.ones((cfg['kernel_size'], cfg['kernel_size']), np.uint8)
binary = cv2.dilate(binary, kernel, iterations=1)
return binary
def ocr_recognize(self, image: np.ndarray) -> Dict:
"""OCR文字识别"""
if self.config.config['ocr_engine'] == 'tesseract':
return pytesseract.image_to_data(
image,
config=self.tessdata_config,
output_type=pytesseract.Output.DICT
)
else:
raise ValueError("不支持的OCR引擎")
def find_text_positions(self, text_pattern: str, refresh: bool = False) -> Dict[str, Tuple[int, int]]:
"""查找文本位置"""
if not refresh and text_pattern in self.text_cache:
return self.text_cache[text_pattern]
screen_img = self.capture_screen()
processed_img = self.preprocess_image(screen_img)
ocr_data = self.ocr_recognize(processed_img)
positions = {}
for i in range(len(ocr_data['text'])):
text = ocr_data['text'][i].strip()
if text and re.search(text_pattern, text, re.IGNORECASE):
x, y = ocr_data['left'][i], ocr_data['top'][i]
w, h = ocr_data['width'][i], ocr_data['height'][i]
center_x = x + w // 2
center_y = y + h // 2
positions[text] = (center_x, center_y, w, h)
self.text_cache[text_pattern] = positions
return positions
def click_text(self, text_pattern: str, click_type: str = 'left', offset: Tuple[int, int] = (0, 0)) -> bool:
"""点击识别到的文本"""
positions = self.find_text_positions(text_pattern)
if not positions:
print(f"[失败] 未找到匹配文本: {text_pattern}")
return False
for text, (x, y, w, h) in positions.items():
target_x = x + offset[0]
target_y = y + offset[1]
print(f"[成功] 找到文本: {text} 位置: ({target_x}, {target_y}) 大小: {w}x{h}")
pyautogui.moveTo(target_x, target_y, duration=self.config.config['click']['move_duration'])
time.sleep(self.config.config['click']['delay'])
if click_type == 'left':
pyautogui.click()
elif click_type == 'right':
pyautogui.rightClick()
elif click_type == 'double':
pyautogui.doubleClick()
elif click_type == 'middle':
pyautogui.middleClick()
print(f"[操作] 已{click_type}点击: {text}")
return True
return False
def run_automation(self, text_patterns: List[str], click_type: str = 'left', interval: float = None):
"""运行自动化任务"""
self.running = True
interval = interval or self.config.config['scan_interval']
print(f"自动化任务开始运行,扫描间隔: {interval}秒...")
try:
while self.running:
for pattern in text_patterns:
if not self.running:
break
attempts = 0
while attempts < self.config.config['max_attempts']:
if self.click_text(pattern, click_type):
break
attempts += 1
time.sleep(0.5)
time.sleep(interval)
except KeyboardInterrupt:
print("\n[停止] 用户中断操作")
except Exception as e:
print(f"\n[错误] 发生异常: {str(e)}")
finally:
self.running = False
def parse_arguments():
parser = argparse.ArgumentParser(description='高级文字识别自动点击器')
parser.add_argument('-t', '--text', action='append', help='要识别的文本模式(支持正则)')
parser.add_argument('-f', '--file', help='包含多个文本模式的文件')
parser.add_argument('-c', '--config', help='配置文件路径')
parser.add_argument('--click-type', default='left',
choices=['left', 'right', 'double', 'middle'],
help='点击类型 (default: left)')
parser.add_argument('--region', nargs=4, type=int,
help='屏幕区域(x1 y1 x2 y2)')
parser.add_argument('--interval', type=float,
help='扫描间隔(秒)')
parser.add_argument('--debug', action='store_true',
help='启用调试模式')
return parser.parse_args()
def main():
args = parse_arguments()
# 初始化配置
config = TextAutoClickerConfig(args.config)
if args.region:
config.config['region'] = args.region
if args.interval:
config.config['scan_interval'] = args.interval
# 创建点击器实例
clicker = TextAutoClicker(config)
# 加载文本模式
text_patterns = []
if args.file:
try:
with open(args.file, 'r', encoding='utf-8') as f:
text_patterns.extend(line.strip() for line in f if line.strip())
except Exception as e:
print(f"加载文本模式文件失败: {str(e)}")
sys.exit(1)
if args.text:
text_patterns.extend(args.text)
if not text_patterns:
print("错误: 必须指定至少一个文本模式(--text或--file)")
sys.exit(1)
# 运行自动化
try:
clicker.run_automation(text_patterns, args.click_type)
except Exception as e:
print(f"发生错误: {str(e)}")
sys.exit(1)
if name == 'main':
main()