ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Python + PyAutoGUI 一键清理实战:OpenCV 图像识别 + TaoToken 配置骨架

Python + PyAutoGUI 一键清理实战:OpenCV 图像识别 + TaoToken 配置骨架 1. 从 148 个 Skills 说起为什么我要写这个清理脚本如果你也在 Windows 上折腾过桌面工具大概率遇到过这种场景某个软件里堆了几百条记录界面只给了一个一个删的按钮没有批量选择没有全选没有清空。我这次碰到的就是 CC Switch 里积攒了 148 个 Skills删除操作还分两步——先点删除再点确认弹窗。148 乘 2接近 300 次鼠标点击手动点完手都酸了。这类「重复两步点击」的需求正好是 Python 桌面自动化的经典靶子。核心工具就三个PyAutoGUI 负责模拟鼠标键盘OpenCV 负责在屏幕上找按钮TaoToken 负责给脚本里可能用到的模型调用提供统一 Key 和 API 通道。这篇文章不聊虚的直接交付一条从截图到自动执行的最小闭环怎么用模板匹配定位按钮、阈值参数怎么调、点击坐标怎么校准、配置骨架怎么写、跑完怎么验证成功。适合谁看会一点 Python、想在 Windows 上做桌面自动化、又不想把简单问题搞复杂的人。我会先讲清楚 OpenCV 图像识别什么时候该用、什么时候是杀鸡用牛刀再给出可复制的配置和排错清单。整条链路跑通后你删的不只是 Skills任何「固定两步确认」的界面都能套这个骨架。2. TaoToken 前置统一 Key 与 API 通道的配置骨架在动手写点击逻辑之前先把「配置层」搭好。原因很简单自动化脚本一旦要接入模型能力比如让模型判断当前界面状态、生成清理规则、或者做异常截图描述Key 和 API 地址散落在代码里会非常难维护。TaoToken 提供的是统一的 Key 和 API 通道官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 。我习惯把配置拆成两份一份config.toml放非敏感的结构化参数一份settings.json放运行时状态和 Key 引用。这样脚本逻辑和配置解耦换环境只改配置不动代码。先看config.toml它管的是「脚本怎么跑」# config.toml —— 自动化清理脚本主配置 [app] name desktop-cleaner version 0.1.0 log_level INFO [taotoken] # 统一 API 通道不要在这里写死 Key用环境变量注入 api_base https://taotoken.net/api api_key_env TAOTOKEN_API_KEY default_model claude-sonnet timeout_seconds 30 [vision] # OpenCV 模板匹配参数 match_threshold 0.82 template_dir ./templates screenshot_scale 1.0 [click] # 点击节奏控制 interval_seconds 0.5 move_duration 0.15 failsafe true再看settings.json它管的是「这次跑的具体状态」包括校准出来的坐标{ taotoken: { api_base: https://taotoken.net/api, api_key_ref: env:TAOTOKEN_API_KEY, model: claude-sonnet }, calibration: { delete_button: [1856, 320], confirm_button: [960, 540], screen_size: [1920, 1080], dpi_scale: 1.0 }, runtime: { click_count: 0, last_run: null, dry_run: true } }这里有个关键设计api_key_ref写的是env:TAOTOKEN_API_KEY意思是运行时从环境变量读取而不是把 Key 明文塞进 JSON。Windows 下设置环境变量setx TAOTOKEN_API_KEY 你的Key设置完要重开终端才生效。Key 的获取入口在控制台的 API Keys 页面地址是 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。拿到 Key 后先别急着写业务代码用一条最小请求验证通道是否通import os, requests api_base https://taotoken.net/api key os.environ[TAOTOKEN_API_KEY] resp requests.post( f{api_base}/v1/chat/completions, headers{Authorization: fBearer {key}}, json{ model: claude-sonnet, messages: [{role: user, content: 回复 OK 两个字母}], max_tokens: 16 }, timeout30 ) print(resp.status_code, resp.json()[choices][0][message][content])返回200 OK就说明 Key 和通道都正常。这一步别跳过后面脚本里所有模型调用都依赖它。如果你只是想先验证模型能不能通可以直接在模型对话页面手动发一条消息地址是 https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 比写代码更快。3. 可复制配置OpenCV 模板匹配 PyAutoGUI 点击校准配置层就绪后进入核心的识别与点击部分。先装依赖pip install pyautogui opencv-python numpy keyboard requests3.1 截图与模板匹配的阈值参数OpenCV 模板匹配的原理是拿一张小图按钮模板在大图屏幕截图上滑动逐像素算相似度返回一个相似度矩阵。cv2.matchTemplate支持多种算法做按钮识别我固定用TM_CCOEFF_NORMED它的结果在 -1 到 1 之间越接近 1 越像。import cv2 import numpy as np import pyautogui def grab_screen(): 截取全屏并转成 OpenCV 的 BGR 格式 shot pyautogui.screenshot() return cv2.cvtColor(np.array(shot), cv2.COLOR_RGB2BGR) def find_template(screen_bgr, template_path, threshold0.82): 在屏幕中查找模板返回中心坐标或 None template cv2.imread(template_path) if template is None: raise FileNotFoundError(f模板不存在: {template_path}) res cv2.matchTemplate(screen_bgr, template, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc cv2.minMaxLoc(res) if max_val threshold: return None, max_val h, w template.shape[:2] center_x max_loc[0] w // 2 center_y max_loc[1] h // 2 return (center_x, center_y), max_val阈值0.82是我实测下来比较稳的起点。调参规律是这样的阈值太高0.95 以上界面稍有缩放或抗锯齿差异就匹配不到阈值太低0.7 以下容易把相似图标误判成目标按钮。建议先用 0.82 跑如果漏检就降到 0.78如果误检就升到 0.88。模板图要截得干净只包含按钮本身别带周围背景。3.2 点击坐标校准脚本模板匹配能自动找位置但有些按钮长得太像比如列表里每行都有删除图标这时候模板匹配会返回一堆候选点。我的做法是先用模板匹配做粗定位再用一次「手动校准」把最终坐标固化下来。校准脚本长这样import json import time import pyautogui SETTINGS settings.json def load_settings(): with open(SETTINGS, r, encodingutf-8) as f: return json.load(f) def save_settings(data): with open(SETTINGS, w, encodingutf-8) as f: json.dump(data, f, ensure_asciiFalse, indent2) def calibrate(): data load_settings() print(3 秒后记录鼠标位置请把鼠标移到【删除按钮】上...) time.sleep(3) delete_pos list(pyautogui.position()) print(f删除按钮坐标: {delete_pos}) print(3 秒后记录鼠标位置请把鼠标移到【确认按钮】上...) time.sleep(3) confirm_pos list(pyautogui.position()) print(f确认按钮坐标: {confirm_pos}) data[calibration][delete_button] delete_pos data[calibration][confirm_button] confirm_pos data[calibration][screen_size] list(pyautogui.size()) save_settings(data) print(校准完成已写入 settings.json) if __name__ __main__: calibrate()跑一次校准坐标就固化进settings.json。之后脚本优先用固化坐标点击模板匹配只作为「界面变了」时的兜底检测。这样既快又稳。3.3 完整清理流程的点击逻辑把识别和点击串起来就是一次完整的清理动作import time import pyautogui def do_one_clean(delete_pos, confirm_pos, interval0.5): 执行一次删除确认 pyautogui.moveTo(delete_pos[0], delete_pos[1], duration0.15) pyautogui.click() time.sleep(interval) pyautogui.moveTo(confirm_pos[0], confirm_pos[1], duration0.15) pyautogui.click() time.sleep(interval) def run_clean_loop(delete_pos, confirm_pos, total, interval0.5): 循环清理 total 次 for i in range(total): do_one_clean(delete_pos, confirm_pos, interval) if (i 1) % 10 0: print(f已完成 {i 1} / {total}) print(f清理结束共执行 {total} 次)interval默认 0.5 秒别调太小。界面弹窗有动画点太快确认框还没出来第二次点击就落空了。我试过 0.2 秒结果十次里有三次没点到确认反而更慢。4. 验证请求与成功结果跑通最小闭环配置和代码都齐了现在验证整条链路。验证分三层从下往上逐层确认。第一层验证 TaoToken 通道。前面那段requests代码返回200 OK就算过。如果返回 401说明 Key 没读到或写错了返回 404检查api_base是不是写成了带路径的地址。第二层验证模板匹配。先截一张当前屏幕再跑find_template看返回的坐标和相似度screen grab_screen() pos, score find_template(screen, ./templates/delete_button.png, threshold0.82) print(f匹配坐标: {pos}, 相似度: {score:.4f})相似度在 0.85 以上坐标落在按钮附近就说明模板和阈值都合适。如果pos是None看score是多少——0.7 到 0.8 之间说明模板对但阈值偏高降到 0.78 再试低于 0.6 说明模板截得不对重新截。第三层验证完整清理流程。先开dry_run模式只打印不点击data load_settings() delete_pos data[calibration][delete_button] confirm_pos data[calibration][confirm_button] if data[runtime][dry_run]: print(f[DRY RUN] 将点击删除 {delete_pos}确认 {confirm_pos}) else: run_clean_loop(delete_pos, confirm_pos, total5)确认坐标无误后把dry_run改成false先跑 5 次小批量。观察日志[21:30:05] 删除按钮坐标: [1856, 320] [21:30:10] 确认按钮坐标: [960, 540] [21:30:15] 开始清理... [21:30:20] 已完成 5 / 5 [21:30:20] 清理结束共执行 5 次5 次都成功再放大到 148 次。跑的时候把鼠标移到屏幕左上角可以触发 PyAutoGUI 的 FAILSAFE 强制停止这是最后的安全绳。5. 本篇常见错排查点击偏移、匹配失败、热键失灵自动化脚本跑不起来九成是下面这几类问题。我按踩坑频率排个序。点击位置整体偏移。最常见的原因是高 DPI 缩放。Windows 在 125% 或 150% 缩放下PyAutoGUI 拿到的坐标和实际屏幕像素对不上。解决办法右键 Python 解释器或脚本 → 属性 → 兼容性 → 更改高 DPI 设置 → 勾选「替代高 DPI 缩放行为」缩放执行选「应用程序」。改完重启终端再跑。模板匹配一直返回 None。先确认模板图是不是用同一台机器、同一缩放比例截的。换机器或改缩放后模板必须重截。其次检查模板路径cv2.imread遇到中文路径会静默返回 None路径尽量用英文。最后看阈值界面主题变了浅色变深色也会导致相似度骤降重新截模板比调阈值靠谱。热键按了没反应。keyboard库在 Windows 下监听全局热键需要管理员权限。用管理员身份开终端再跑脚本。另外某些安全软件会拦截全局键盘钩子临时加白名单即可。点击落空、确认框没出来。把interval从 0.5 调到 0.8 试试。界面动画慢的时候0.5 秒确实不够。还有一种情况是弹窗位置不固定这时候就不能用固化坐标得回到模板匹配动态定位。脚本跑一半卡死。多半是pyautogui的 FAILSAFE 被触发或者某次点击打开了新窗口导致后续坐标全错。加一层异常捕获出错时打印当前屏幕截图方便事后分析try: run_clean_loop(delete_pos, confirm_pos, total148) except Exception as e: pyautogui.screenshot(error_state.png) print(f出错: {e}已保存 error_state.png)排障时如果怀疑是 Key 或通道问题直接去接入文档对照参数地址是 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 里面有完整的请求格式和错误码说明。6. 把骨架用起来从清理脚本到长期自动化这套骨架跑通后你会发现它能复用的地方比想象中多。批量删除文件、游戏里重复放技能、表单批量填写、数据采集翻页本质都是「定位元素 → 执行动作 → 循环」这三步。区别只在于元素是固定坐标还是动态识别。如果你打算把这类脚本长期跑下去尤其是接入模型做智能判断比如让模型看截图决定下一步点哪建议把 Key 管理收敛到一处。短期试验用按量计费的 API Key 就够长期高频调用可以看看 Coding Plan 的额度方案地址是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 适合需要稳定通道的编码和 Agent 场景。最后说个我自己的习惯任何自动化脚本第一次跑真实数据前一定先跑dry_run再跑 5 次小批量确认无误才放开全量。148 次点击听起来不多但点错位置把不该删的东西删了恢复起来可比手动点 296 下麻烦多了。脚本是工具安全绳得自己系。
返回列表