本文目录导读:

完整脚本
import pyautogui
import cv2
import numpy as np
import time
import os
from datetime import datetime
# 配置参数
TEMPLATE_IMAGE = "popup_template.png" # 弹窗模板图片路径
SCREENSHOT_DIR = "screenshots" # 截图保存目录
CLICK_DELAY = 0.5 # 点击后延迟(秒)
CHECK_INTERVAL = 2 # 检测间隔(秒)
CONFIDENCE_THRESHOLD = 0.8 # 匹配置信度阈值
class PopupClicker:
def __init__(self):
# 创建截图目录
if not os.path.exists(SCREENSHOT_DIR):
os.makedirs(SCREENSHOT_DIR)
# 加载模板图像
self.template = cv2.imread(TEMPLATE_IMAGE, cv2.IMREAD_GRAYSCALE)
if self.template is None:
raise FileNotFoundError(f"找不到模板图片: {TEMPLATE_IMAGE}")
self.template_height, self.template_width = self.template.shape
def find_popup(self):
"""查找弹窗位置"""
# 截取当前屏幕
screenshot = pyautogui.screenshot()
screenshot = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
gray_screenshot = cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY)
# 模板匹配
result = cv2.matchTemplate(gray_screenshot, self.template, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
print(f"最大匹配度: {max_val:.2f} (阈值: {CONFIDENCE_THRESHOLD})")
if max_val >= CONFIDENCE_THRESHOLD:
# 计算弹窗中心位置
center_x = max_loc[0] + self.template_width // 2
center_y = max_loc[1] + self.template_height // 2
return (center_x, center_y)
return None
def click_and_screenshot(self, position):
"""点击弹窗并截图"""
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
# 截图点击前状态
before_screenshot = pyautogui.screenshot()
before_screenshot.save(os.path.join(SCREENSHOT_DIR, f"click_before_{timestamp}.png"))
print(f"已保存点击前截图: click_before_{timestamp}.png")
# 点击弹窗中心
pyautogui.click(position[0], position[1])
print(f"已点击位置: {position}")
# 等待弹窗反应
time.sleep(CLICK_DELAY)
# 截图点击后状态
after_screenshot = pyautogui.screenshot()
after_screenshot.save(os.path.join(SCREENSHOT_DIR, f"click_after_{timestamp}.png"))
print(f"已保存点击后截图: click_after_{timestamp}.png")
return True
def run(self):
"""主循环"""
print(f"开始监控弹窗 (模板: {TEMPLATE_IMAGE}, 置信度阈值: {CONFIDENCE_THRESHOLD})")
print(f"截图保存目录: {os.path.abspath(SCREENSHOT_DIR)}")
while True:
try:
position = self.find_popup()
if position:
print(f"检测到弹窗,位置: {position}")
self.click_and_screenshot(position)
else:
print("未检测到弹窗")
# 等待下一次检测
time.sleep(CHECK_INTERVAL)
except KeyboardInterrupt:
print("\n脚本已停止")
break
except Exception as e:
print(f"发生错误: {e}")
time.sleep(CHECK_INTERVAL)
if __name__ == "__main__":
# 安全提示
print("警告: 脚本将在指定位置持续运行。")
print("将鼠标移动到屏幕左上角可紧急停止。")
pyautogui.FAILSAFE = True # 启用安全模式
clicker = PopupClicker()
clicker.run()
使用步骤
安装依赖
pip install pyautogui opencv-python pillow numpy
准备模板图片
- 截取一张弹窗的截图(只包含弹窗部分)
- 保存为
popup_template.png放在脚本同一目录 - 建议使用图片编辑软件裁剪为精确的弹窗形状
运行脚本
python popup_clicker.py
功能特点
- 模板匹配检测:使用OpenCV对弹窗进行精确匹配
- 自动截图:点击前后都会保存屏幕截图
- 安全机制:鼠标移到屏幕左上角可紧急停止
- 可配置参数:可根据需要调整检测间隔、置信度等
- 错误处理:完善的异常处理机制
配置参数说明
| 参数 | 说明 | 默认值 |
|---|---|---|
| TEMPLATE_IMAGE | 弹窗模板图片路径 | popup_template.png |
| SCREENSHOT_DIR | 截图保存目录 | screenshots |
| CLICK_DELAY | 点击后延迟(秒) | 5 |
| CHECK_INTERVAL | 检测间隔(秒) | 2 |
| CONFIDENCE_THRESHOLD | 匹配置信度阈值 | 8 |
实现原理
- 截图:使用
pyautogui.screenshot()捕获屏幕 - 模板匹配:通过OpenCV的
matchTemplate函数定位弹窗 - 自动点击:使用
pyautogui.click()模拟鼠标点击 - 截图保存:点击前后自动截图存档
注意事项
- 管理员权限:某些场景下可能需要管理员权限
- 屏幕分辨率:确保模板图片与弹窗分辨率匹配
- 多显示器:默认只检测主显示器
- 弹窗透明度:透明度高的弹窗可能检测失败
进阶功能
如需支持更复杂的场景,可以扩展以下功能:
# 多模板匹配 TEMPLATE_IMAGES = ["popup1.png", "popup2.png", "popup3.png"] # 支持区域检测 REGION = (100, 200, 500, 400) # (x, y, width, height) # 自定义点击位置偏移 CLICK_OFFSET = (10, 20) # 相对于模板左上角的偏移
这个脚本会自动监控屏幕上的弹窗,点击后截图保存,非常适合需要批量处理弹窗屏幕的程序测试场景。