前言
上篇文章说到我装了 148 个 Skills 到 CC Switch 里,想清理却发现根本没有批量删除功能。没办法,只能自己动手写脚本。
这篇文章记录了我的自动化方案演进过程------从一开始想用 OpenCV 搞图像识别,到最后发现一个简单的 PyAutoGUI 脚本就能搞定。 有时候最土的方案反而是最好的方案。
需求很明确
CC Switch 的删除操作分两步:
-
点击删除按钮
-
弹出确认框后,点击确认
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])
但很快我就发现这个方案太蠢了:
-
需要截图模板:不同分辨率、不同主题下按钮长得不一样,模板匹配可能失灵
-
窗口位置会变:CC Switch 窗口每次打开位置可能不同
-
杀鸡用牛刀:我就点两个固定位置的按钮,至于上 CV 吗?
-
开发时间太长:调模板匹配参数、处理各种边界情况,比手动删还费时间
果断放弃。
方案二:PyAutoGUI + 全局热键(最终方案)
冷静下来一想,我要做的其实就是一个"按键精灵":
-
先手动把鼠标移到删除按钮上,记录坐标
-
再手动把鼠标移到确认按钮上,记录坐标
-
让脚本循环点击这两个位置
就这么简单,根本不需要图像识别。
技术选型
| 库 | 用途 |
|---|---|
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,还可以用于:
| 场景 | 说明 |
|---|---|
| 批量删除文件 | 任何需要反复确认删除的场景 |
| 游戏挂机 | 设置技能按钮位置,自动释放技能 |
| 表单填写 | 设置输入框位置,自动粘贴内容 |
| 数据采集 | 设置翻页按钮位置,自动翻页 |
注意事项
-
管理员权限:Windows 下全局热键可能需要管理员权限运行
-
安全停止:除了 F3,也可以把鼠标快速移到屏幕左上角强制停止(PyAutoGUI 默认开启 FAILSAFE)
-
点击间隔:代码里默认 0.5 秒一次,可根据需要调整
-
DPI 缩放:如果点击位置偏移,可能是高 DPI 屏幕缩放问题,右键脚本 → 属性 → 兼容性 → 更改高 DPI 设置
结语
这次经历最大的感悟就是:
写自动化脚本最忌讳"想太多"。
明明一个土办法 5 分钟就能搞定的事情,非得上 OpenCV、机器学习、深度学习三件套,结果调参调到怀疑人生。很多时候最简单的方案就是最好的方案。
代码不到 150 行,但解决了实际问题。Python 自动化真的很强!
如果这篇文章对你有帮助,欢迎点赞收藏!有问题欢迎评论区讨论。