当前位置: 首页 > news >正文

Python + PyAutoGUI 实现一键清理:从 OpenCV 图像识别到“按键精灵“的自动化之路

前言

上篇文章说到我装了 148 个 Skills 到 CC Switch 里,想清理却发现根本没有批量删除功能。没办法,只能自己动手写脚本。

这篇文章记录了我的自动化方案演进过程——从一开始想用 OpenCV 搞图像识别,到最后发现一个简单的 PyAutoGUI 脚本就能搞定。有时候最土的方案反而是最好的方案。


需求很明确

CC Switch 的删除操作分两步:

  1. 点击删除按钮

  2. 弹出确认框后,点击确认

148 个 Skills,每个都要重复这两个动作。手动点 296 下?疯了吧。


方案一:OpenCV 图像识别(想多了)

我的第一反应是用 OpenCV 做图像识别,自动找到删除按钮和确认按钮。

思路大概是这样的:

python

import cv2 import pyautogui import numpy as np # 截屏 screenshot = pyautogui.screenshot() screen = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR) # 加载按钮模板 delete_template = cv2.imread('delete_button.png') confirm_template = cv2.imread('confirm_button.png') # 模板匹配 res = cv2.matchTemplate(screen, delete_template, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # 点击 if max_val > 0.8: pyautogui.click(max_loc[0], max_loc[1])

但很快我就发现这个方案太蠢了:

  1. 需要截图模板:不同分辨率、不同主题下按钮长得不一样,模板匹配可能失灵

  2. 窗口位置会变:CC Switch 窗口每次打开位置可能不同

  3. 杀鸡用牛刀:我就点两个固定位置的按钮,至于上 CV 吗?

  4. 开发时间太长:调模板匹配参数、处理各种边界情况,比手动删还费时间

果断放弃。


方案二:PyAutoGUI + 全局热键(最终方案)

冷静下来一想,我要做的其实就是一个"按键精灵":

  1. 先手动把鼠标移到删除按钮上,记录坐标

  2. 再手动把鼠标移到确认按钮上,记录坐标

  3. 让脚本循环点击这两个位置

就这么简单,根本不需要图像识别。


技术选型

用途
pyautogui模拟鼠标点击、获取鼠标位置
keyboard全局热键监听
json保存配置,下次直接用

安装:

bash

pip install pyautogui keyboard

完整代码

python

#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 简单点击机器人 快捷键获取鼠标位置,自动循环点击 """ import pyautogui import time import json import os import sys try: import keyboard except ImportError: print("请先安装: pip install keyboard") sys.exit(1) SAVE_FILE = "click_points.json" # 全局状态 delete_pos = None confirm_pos = None running = False def log(msg): print(f"[{time.strftime('%H:%M:%S')}] {msg}") def save_config(): data = {"delete": delete_pos, "confirm": confirm_pos} with open(SAVE_FILE, 'w') as f: json.dump(data, f) log(f"配置已保存") def load_config(): global delete_pos, confirm_pos if os.path.exists(SAVE_FILE): with open(SAVE_FILE, 'r') as f: data = json.load(f) delete_pos = data.get("delete") confirm_pos = data.get("confirm") if delete_pos: log(f"已加载: 删除按钮 {delete_pos}") if confirm_pos: log(f"已加载: 确认按钮 {confirm_pos}") return True return False def get_mouse_pos(): """获取当前鼠标位置""" x, y = pyautogui.position() return (x, y) def set_delete_pos(): """设置删除按钮位置""" global delete_pos delete_pos = get_mouse_pos() log(f"删除按钮位置: {delete_pos}") save_config() def set_confirm_pos(): """设置确认按钮位置""" global confirm_pos confirm_pos = get_mouse_pos() log(f"确认按钮位置: {confirm_pos}") save_config() def do_click(): """执行一次点击流程""" global running if not delete_pos: log("请先设置删除按钮位置 (F1)") return # 点击删除 pyautogui.click(delete_pos[0], delete_pos[1]) time.sleep(0.3) # 确认 if confirm_pos: pyautogui.click(confirm_pos[0], confirm_pos[1]) else: pyautogui.press('enter') time.sleep(0.3) def start_clicking(): """开始自动点击""" global running if running: return if not delete_pos: log("请先设置删除按钮位置 (F1)") return running = True log("开始自动点击...") count = 0 while running: do_click() count += 1 if count % 10 == 0: log(f"已点击 {count} 次") time.sleep(0.5) log(f"停止,共点击 {count} 次") def stop_clicking(): """停止点击""" global running running = False def toggle_clicking(): """切换开始/停止""" if running: stop_clicking() else: import threading t = threading.Thread(target=start_clicking) t.daemon = True t.start() def main(): print("=" * 50) print(" 简单点击机器人") print("=" * 50) print() print("快捷键:") print(" F1 = 设置删除按钮位置 (鼠标移到位置后按F1)") print(" F2 = 设置确认按钮位置 (鼠标移到位置后按F2)") print(" F3 = 开始/停止 自动点击") print(" F4 = 退出程序") print() print("使用步骤:") print(" 1. 把鼠标移到删除按钮上,按 F1") print(" 2. 手动点一下删除,等确认弹窗出来") print(" 3. 把鼠标移到确认按钮上,按 F2") print(" 4. 按 F3 开始自动点击") print(" 5. 再按 F3 停止") print() # 加载配置 load_config() # 注册热键 keyboard.add_hotkey('f1', set_delete_pos) keyboard.add_hotkey('f2', set_confirm_pos) keyboard.add_hotkey('f3', toggle_clicking) keyboard.add_hotkey('f4', lambda: os._exit(0)) log("热键已注册,等待操作...") # 保持运行 try: while True: time.sleep(1) except KeyboardInterrupt: pass if __name__ == "__main__": main()

使用方法

快捷键功能
F1记录删除按钮位置
F2记录确认按钮位置
F3开始/停止 自动点击
F4退出程序

操作步骤:

text

步骤1: 把鼠标移到删除按钮上 → 按 F1 步骤2: 手动点一下删除,等确认弹窗出来 步骤3: 把鼠标移到确认按钮上 → 按 F2 步骤4: 按 F3 开始自动点击 步骤5: 再按 F3 停止

运行效果:

text

================================================== 简单点击机器人 ================================================== 快捷键: F1 = 设置删除按钮位置 (鼠标移到位置后按F1) F2 = 设置确认按钮位置 (鼠标移到位置后按F2) F3 = 开始/停止 自动点击 F4 = 退出程序 [21:30:00] 热键已注册,等待操作... [21:30:05] 删除按钮位置: (1856, 320) [21:30:10] 确认按钮位置: (960, 540) [21:30:15] 开始自动点击... [21:30:45] 已点击 10 次 [21:31:15] 已点击 20 次 [21:31:20] 停止,共点击 22 次

核心设计思路

1. 为什么不用图像识别?

一句话:坐标固定的场景下,图像识别纯属多余。

图像识别适合按钮位置会变化的场景(比如网页上滚动加载的内容)。但 CC Switch 的窗口位置是你自己打开的,删除按钮和确认按钮的位置基本固定。这种情况下,手动标一次坐标比调半天 CV 参数快得多。

2. 多线程点击

python

def toggle_clicking(): if running: stop_clicking() else: import threading t = threading.Thread(target=start_clicking) t.daemon = True t.start()

点击循环在独立线程中运行,不阻塞主线程,这样才能随时按 F3 停止。

3. 配置持久化

位置信息自动保存到click_points.json,下次打开脚本直接用,不用重新标记。


方案对比总结

方案复杂度适用场景本次评价
手动点10个以内太累
OpenCV 图像识别按钮位置不确定杀鸡用牛刀
PyAutoGUI + 热键按钮位置固定✅ 最合适

扩展应用

这个脚本不只是用来删 Skills,还可以用于:

场景说明
批量删除文件任何需要反复确认删除的场景
游戏挂机设置技能按钮位置,自动释放技能
表单填写设置输入框位置,自动粘贴内容
数据采集设置翻页按钮位置,自动翻页

注意事项

  1. 管理员权限:Windows 下全局热键可能需要管理员权限运行

  2. 安全停止:除了 F3,也可以把鼠标快速移到屏幕左上角强制停止(PyAutoGUI 默认开启 FAILSAFE)

  3. 点击间隔:代码里默认 0.5 秒一次,可根据需要调整

  4. DPI 缩放:如果点击位置偏移,可能是高 DPI 屏幕缩放问题,右键脚本 → 属性 → 兼容性 → 更改高 DPI 设置


结语

这次经历最大的感悟就是:

写自动化脚本最忌讳"想太多"。

明明一个土办法 5 分钟就能搞定的事情,非得上 OpenCV、机器学习、深度学习三件套,结果调参调到怀疑人生。很多时候最简单的方案就是最好的方案。

代码不到 150 行,但解决了实际问题。Python 自动化真的很强!


如果这篇文章对你有帮助,欢迎点赞收藏!有问题欢迎评论区讨论。

http://www.jsqmd.com/news/735108/

相关文章:

  • 基于MCP协议的ZPL标签打印引擎:连接AI与工业打印的桥梁
  • 告别迷茫!GNSS数据处理从入门到实战:这10款免费/开源软件我帮你试过了
  • 口碑好的新疆生态修复哪个公司更靠谱
  • 告别70分贝噪音!手把手教你用100W冰箱压缩机DIY静音真空泵(附详细配件清单)
  • volatile与信号
  • 别再用namespace凑合了!MCP 2026强制启用Cgroups v2 + PSI反馈控制后,租户资源争抢下降83%(实测数据)
  • Missy:构建安全可控的本地AI助手平台,从零部署到高级应用
  • 金融机构多功能厅隔间定制品牌推荐:写字楼隔断、医院隔断、可拆装隔断、商业空间隔断、商场隔断、学校隔断、宴会厅隔断选择指南 - 优质品牌商家
  • DoRA:超越LoRA的高效微调方法解析
  • 婚礼筹备进行曲
  • 实测Taotoken调用大模型的延迟与稳定性观感分享
  • 2026仿真绿植绿化工程厂家权威评测报告:园林造景绿化工程/园林造景绿化电话/屋顶绿化电话/立体绿化工程/立体绿化电话/选择指南 - 优质品牌商家
  • Taotoken 用量看板如何帮助项目精准控制 API 成本
  • 在瑞芯微RK3588上集成YOLOv8检测与分割模型:一个C++工程的完整CMakeLists配置与避坑指南
  • 强化学习微调提升代码生成质量:TAROT框架解析
  • 大语言模型推理成本计算与优化实战
  • 2026一站式等保测评复测全解析:一站式信息网络安全等级保护等保测评复测、互联网信息服务业务在线数据处理与交易处理业务ICP选择指南 - 优质品牌商家
  • day02 数组前缀和 / 区间排序
  • AMD笔记本也能丝滑黑苹果?我用小新Pro16 2021款+Sonoma趟平了所有坑
  • ## 一文看懂HPH硬件的核心构造与工作原理
  • 2026合肥市蜀山区专业回收品牌全景介绍:合肥市蜀山区废旧电线/合肥市蜀山区废铁回收/合肥市蜀山区废铝回收/合肥市蜀山区电缆回收/选择指南 - 优质品牌商家
  • c语言开发者如何通过curl快速调用taotoken聚合大模型api
  • 《现代 Python 桌面应用架构实战:PySide6 + QML 从入门到工程化》:动态数据仪表盘与 NumPy 可视化 —— 从标量到向量的数据驱动进化
  • AI Agent应用类型及Function Calling开发实战(二)
  • 《灵魂摆渡・浮生梦》抢占流量高地,海棠山铁哥《第一大道》凭实力突围出圈
  • easyclaw:简化网络数据抓取的轻量级Python工具库
  • 2026香格里拉草原民宿口碑评估:香格里拉度假酒店、香格里拉旅行住宿、香格里拉民宿种草、香格里拉疗愈民宿、香格里拉网红民宿选择指南 - 优质品牌商家
  • 2026年4月土壤检测怎么选:甲醛检测、苯系物检测、CMA检测、CMA第三方检验检测、公共卫生检测、公共卫生监测选择指南 - 优质品牌商家
  • 外键约束 FOREIGN KEY
  • 浏览器里的魔法工厂:NormalMap-Online让2D图片瞬间拥有3D质感