
简介RPAworker简易自动化工具是一款面向零基础办公人员的RPA自动化辅助软件采用图片定位与Excel指令编排相结合的方式让用户通过截图和表格设置就能生成自动化流程工具支持近40个操作指令可按照从上到下的顺序逐条执行覆盖报表下载、表单填写、重复点击等日常办公场景有效减少机械化重复操作。其配置逻辑直观把界面元素截图作为定位依据在Excel表中按顺序填写操作指令即可生成可重复运行的流程后期修改只需调整表格内容。使用者无需编程语言基础只要掌握截图与Excel基本操作即可自行配置若后续学习一点数据库知识还可借助同一套逻辑搭建网页爬虫采集数据把自动化范围扩展到网络端。资源包为zip压缩格式大小约76.71MB支持Win7及以上版本服务器需Win2008及以上Win10下运行最稳定Win7若闪退可按系统位数安装vc_redist运行库后正常使用。目前已有251人学习关注对于文员、个人开发者等希望低成本入门RPA的用户而言这份轻量工具可直接下载解压进行流程配置和测试。1. RPAworker简易自动化工具为什么它比“大而全”的RPA平台更适合个人和小团队每天早上一到工位先把三个业务系统的报表导出来照着规则填进Excel再打开网页逐个录入最后发邮件通知——这套动作我做了快一年直到有一天我数了一下每天大概要花四十分钟在这类毫无技术含量的重复操作上。后来我搭了一个RPAworker简易自动化工具把这套流程交给脚本去跑每天只留一道人工复核。RPA这个名字听起来很工业但“简易”两个字才是关键它不追求像企业级RPA平台那样覆盖所有系统、支持流程编排、带控制台管理只解决一件事——把你在电脑上反复做的机械操作用图像识别加键鼠模拟的方式自动跑起来。这套思路特别适合个人开发者、小团队和兼职做数据处理的从业者你不需要部署服务器不需要被审批流程卡住甚至不需要太深的编程功底只要机器上能装Python把几行脚本写得能看懂就行。更重要的是它不依赖被自动化系统的任何接口不侵入对方软件的改造范围窗口在旁边开着它就能干活活干完你只需要盯一眼结果。这篇文章会把从技术选型到实际落地的完整路径讲清楚包括参数怎么调、哪些地方容易翻车、怎么把脚本做得不容易坏。2. 选型先立住简易RPA工具的定位、技术路线与运行环境2.1 三种自动化路线的取舍为什么简易工具选“图像识别键鼠模拟”市面上常见的RPA实现路线大致有三类。第一类基于UI控件树通过系统辅助功能接口读取窗口上的按钮、输入框、表格节点然后直接调用控件的属性去赋值或触发点击。这路线的优点是定位精准、速度快但前提是被自动化程序必须暴露控件树很多自绘界面、网页里的Canvas区域、远程桌面里的窗口都拿不到稳定的控件信息。第二类基于坐标脚本也就是提前记住按钮在屏幕上的像素位置到点就点击。这玩意儿最脆弱窗口一挪、分辨率一换、屏幕上多弹出个通知整套脚本就全偏了。坐标脚本一般只适合固定工位的演示场景真正用来跑日常任务很容易让人血压升高。第三类就是RPAworker这类简易工具采用的路线用截图模板匹配来做视觉定位用键鼠模拟来执行动作。先截取目标按钮或输入框的小图作为模板运行时在屏幕上找到匹配位置再去点击或输入。整套方案不需要接触被控程序内部也不依赖绝对坐标窗口只要在屏幕上可见且外观没大变基本就能找得到、点得准。三者的关键差异我用一张表来梳理路线定位方式环境要求稳定性适用场景控件树读取UI控件接口被控程序暴露控件结构高但挑程序标准Windows桌面应用坐标脚本固定屏幕坐标窗口位置分辨率完全固定低演示、一次性任务图像识别键鼠模拟截图模板匹配目标窗口可见中上靠阈值与容错补救网页、遗留系统、跨平台界面我一般会优先推荐第三类做个人自动化理由很直接它不挑系统不要求对方开放接口连老旧的内部系统都能照跑不误。代价是稍微吃一点CPU以及需要处理匹配失败和误匹配的容错逻辑后面第4章和第5章会展开讲。2.2 简易RPAworker技术栈的选型理由虽然标题叫RPAworker简易自动化工具代码实现上并不需要单独写一个商业级框架。基于它能跑、好维护、够轻量的原则技术栈一般可以收敛为三个部分Python做胶水语言开源的计算机视觉库做模板匹配再加一个跨平台的键鼠控制库做动作执行。常见组合中动作控制用pyautogui它负责模拟鼠标移动、点击、拖拽、键盘输入接口简单到几分钟就能上手自带屏幕截图功能还能顺便用来做调试。图像匹配用OpenCV的模板匹配方法把预先截好的按钮小图作为模板在实时截图中滑动计算相似度返回最可能的中心坐标。中间再加一个watchdog库用于监听文件夹变化当有文件落地时自动触发流程这样就不需要人工去点“开始”按钮。为什么不在这个组合里引入Selenium或Playwright直接操作浏览器因为RPAworker定位的是“所见即所得”的桌面级自动化网页只是其中一类目标。很多内部系统登录后是混合界面一部分页面元素在DOM里一部分是嵌入的桌面控件或Flash遗留物单一浏览器方案根本覆盖不全。而图像识别方案一视同仁——无论那部分是HTML、Canvas还是画出来的按钮只要人眼能看见机器就能按模板去找。2.3 把环境搭起来最小依赖安装与基线验证环境准备按以下命令执行建议先创建独立虚拟环境避免和别的项目打架。python -m venv rpa_env source rpa_env/bin/activate # Windows下用 rpa_env\Scripts\activate pip install pyautogui opencv-python pillow watchdog这几步做完依赖就齐了。pyautogui负责输入模拟opencv-python提供cv2.matchTemplate接口pillow是pyautogui截图时绕不开的图像处理底层库它依赖PIL的接口watchdog用来做文件系统监听。安装完成后先跑一段十秒的验证脚本确认pyautogui能正常控制鼠标键盘import pyautogui import time screen_width, screen_height pyautogui.size() print(f当前屏幕分辨率: {screen_width} x {screen_height}) pyautogui.moveTo(screen_width // 2, screen_height // 2, duration0.5) time.sleep(1) pyautogui.click()这段脚本把鼠标移到屏幕中心并单击。如果运行正常光标会平滑移动过去。逻辑上把这一小段作为基线验证是因为很多环境里pyautogui的鼠标控制受权限限制例如某些远程会话或屏幕设置影响先在最小范围确认它可用可以避免后面写了整套流程才发现底层动作发不出去。参数上moveTo的duration控制移动时长0.5秒代表半秒内完成移动数值越小动作越突兀越大越接近人手移动click不带参数表示在当前光标位置按下左键。3. 核心实现从定位、动作到流程编排跑通一条真实任务3.1 用模板匹配做可靠的目标定位基础代码与匹配参数RPAworker里所有“找东西”的操作都建立在模板匹配上。核心思路是先截取目标区域的图片保存为模板文件程序运行时把屏幕整图读进来用cv2.matchTemplate在整图上滑动搜索最相似的位置。这是OpenCV内置功能不需要训练任何模型模板图片大概几百字节到几KB就能发挥作用。下面这段代码展示一次完整的定位逻辑把“找图标并返回坐标”封装成一个可复用函数import cv2 import numpy as np import pyautogui def find_template(template_path, confidence0.8): # 截取当前屏幕 screen pyautogui.screenshot() # 转为OpenCV使用的BGR格式 screen_cv cv2.cvtColor(np.array(screen), cv2.COLOR_RGB2BGR) # 读取模板图片 template cv2.imread(template_path) # 执行模板匹配 result cv2.matchTemplate(screen_cv, template, cv2.TM_CCOEFF_NORMED) # 找到最相似位置及其相似度 min_val, max_val, min_loc, max_loc cv2.minMaxLoc(result) if max_val confidence: 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 return NonematchTemplate的TM_CCOEFF_NORMED是归一化相关系数匹配结果值域在-1到1之间越接近1代表越相似。confidence参数设置为0.8意思是相似度不低于80%才认为找到目标。这个值不是固定不变的后面讲参数时会细说。取中心坐标是为了让后续点击动作落在模板区域正中央避免点到模板边缘导致误触。如果函数返回None说明屏幕上没找到目标调用方就应该进入等待或重试逻辑而不是直接点击。需要注意的一点是模板图片要截取目标物体的“稳定外观”。例如一个按钮图标尽量只截按钮主体不要带上背景的渐变纹理或旁边的文字否则背景一变匹配率就暴跌。截图分辨率要和运行环境一致建议模板和屏幕都在同一个缩放比例下截取后面遇到缩放的坑会再提。3.2 动作模拟的细节点击、输入、快捷键与等待策略定位到目标之后动作层要处理的主要是四类操作移动并点击、键盘输入、快捷键组合、流程之间的等待。RPAworker在动作层会封装几个常用函数让主流程代码看起来像在描述自然语言步骤。import pyautogui import time import random def smart_click(x, y): # 略微加入随机偏移避免每次点击都在同一个像素点 offset_x random.randint(-3, 3) offset_y random.randint(-3, 3) pyautogui.moveTo(x offset_x, y offset_y, duration0.2) pyautogui.click() def type_text(text, interval0.05): # 逐字符输入模拟人工打字节奏 for char in text: pyautogui.write(char, intervalinterval) def press_hotkey(*keys): # 组合快捷键例如 press_hotkey(ctrl, s) pyautogui.hotkey(*keys) def wait_for(target_func, timeout15): # 轮询等待目标出现超时抛异常 start time.time() while time.time() - start timeout: result target_func() if result is not None: return result time.sleep(1) raise TimeoutError(f{target_func.__name__} 在 {timeout} 秒内未出现)smart_click中加入随机偏移是血泪经验某些系统会记录操作轨迹如果每次点击都在完全相同的像素点很容易触发风控或操作审计告警。type_text逐字符带间隔写入是因为pyautogui.write默认一次性输出整串文本很多网页输入框会直接吞掉部分字符或触发校验这里interval控制每个字符的间隔秒数设0.05秒时速度接近普通人输入既快又不容易丢字。wait_for是整套流程的节拍器RPA最大的翻车点往往是流程跑得太快——界面还没反应过来就执行下一步所以“等待目标出现”比“固定sleep几秒”要可靠得多界面卡顿时固定sleep直接失效而轮询能自动延长等待。3.3 用watchdog监听文件夹让流程自己启动很多自动化任务的触发方式不是“手动运行”而是“有新文件丢进来就开工”。常见场景是业务人员把导出的Excel报表放到一个约定文件夹RPA脚本监测到新文件后自动开始处理。这里用watchdog实现一个轻量监听器比写死循环轮询要省资源得多。from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler import time class RpaJobHandler(FileSystemEventHandler): def on_created(self, event): # 只处理文件创建事件跳过目录 if event.is_directory: return print(f检测到新文件: {event.src_path}) # 这里调用实际的处理流程例如 process_file(event.src_path) def start_monitor(path./jobs): observer Observer() handler RpaJobHandler() observer.schedule(handler, path, recursiveFalse) observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: observer.stop() observer.join()on_created回调只在有新文件创建时触发src_path给出完整路径。之所以用事件监听而不是写while轮询是因为轮询有固定的扫描间隔文件处理时间会被延长事件监听是操作系统层面通知实时性更好CPU占用几乎为零。recursiveFalse表示不递归监听子目录这能避免程序自己往目录里写输出文件时再次触发事件造成无限循环——这一点非常关键输出目录和监听目录必须分开或者输出文件名做排除处理。正式使用中我一般会把监听目录和输出目录分开成两个文件夹这样监听器只看到输入文件处理完毕后把结果写去另一个目录互不干扰。3.4 拼装一个最小但完整的流程把三个模块拧成一股绳前面三个模块单看都简单但串起来就能形成一个完整的自动化闭环。拿一个典型任务举例每天把某个报表软件导出的CSV文件自动合并、填入网页表单并提交。整个流程用伪代码级别就能表达清楚。# run_job.py from finder import find_template from actions import smart_click, type_text, wait_for import pyautogui def process_file(file_path): # 1. 打开目标网页或业务系统 pyautogui.hotkey(ctrl, t) type_text(http://internal-report.example) pyautogui.press(enter) # 2. 等待登录按钮出现 login_btn wait_for(lambda: find_template(templates/login_btn.png)) smart_click(*login_btn[:2]) # 3. 定位文件上传区域填入待处理文件路径 upload_area wait_for(lambda: find_template(templates/upload_area.png)) smart_click(*upload_area[:2]) type_text(file_path) # 4. 点击提交并等待成功页面元素 submit_btn wait_for(lambda: find_template(templates/submit_btn.png)) smart_click(*submit_btn[:2]) ok_icon wait_for(lambda: find_template(templates/success_icon.png), timeout30) print(f文件 {file_path} 处理完成) if __name__ __main__: start_monitor(process_file)上面的代码结构上很清晰find_template负责视觉定位smart_click和type_text负责动作执行wait_for作为流程节拍器。逻辑上每个步骤之间都做了目标出现校验其中任何一步失败都会在wait_for处抛出TimeoutError外层捕获异常后可以归档失败文件、发告警通知。参数上有一个细节容易被忽视type_text填入文件路径时路径中如果有反斜杠建议先做一次路径分隔符替换因为pyautogui.write对反斜杠的处理在不同键盘布局下有差异。一般我会在拼接内容前加一句 path.replace(\, /)牺牲一点Windows路径原生化换取输入环节的稳定。4. 边界参数与可靠性把脚本从“能跑”调到“长期能跑”4.1 匹配置信度与多目标策略什么时候该用0.9什么时候0.7就够了confidence参数的选择不是拍脑袋。目标元素外观越稳定、屏幕环境越干净阈值可以拉得越高。例如登录界面上一个位置固定的按钮背景是纯色模板匹配的峰值通常在0.95以上此时把confidence设为0.9可以有效避免误点。但如果目标元素是表格里的某一行标题栏包含大量相似的行结构多目标并存时最高相似度可能只有0.75左右阈值设得太高就会一直找不到。多目标场景是另一个常见需求窗口里可能有多个相同的“删除”按钮你希望点的是某一行边上的。cv2.matchTemplate直接返回的是全图最高分的位置但对多目标情况需要借助阈值化加连通区域分析来做。def find_all_templates(template_path, confidence0.8): screen pyautogui.screenshot() screen_cv cv2.cvtColor(np.array(screen), cv2.COLOR_RGB2BGR) template cv2.imread(template_path) result cv2.matchTemplate(screen_cv, template, cv2.TM_CCOEFF_NORMED) locations np.where(result confidence) points [] h, w template.shape[:2] for pt in zip(*locations[::-1]): center (pt[0] w // 2, pt[1] h // 2) points.append(center) return points这段代码返回所有相似度超过阈值的目标中心点。注意直接用np.where会把同一个目标附近的重叠区域全部算进来同一按钮周围可能挤出十几个点。实际使用时要再做一步去重按最小距离合并聚类通常设置两个中心点距离小于模板宽度的一半就视为同一个目标。这个去重逻辑建议在流程里实现否则点击“第二个删除按钮”时可能因为重复点导致鼠标在一个按钮上划来划去。4.2 超时、重试与失败归档让脚本具备自我保护意识线上长期跑的脚本最怕的不是功能写错而是某个步骤卡住后无限等待或者失败后把数据弄脏。RPAworker的做法是给每一步加超时超时后重试有限次数最终失败则把输入文件移动到failures目录并记录日志而不是留在原地。import time import shutil from pathlib import Path def run_with_retry(action_func, retries3, timeout15): last_error None for attempt in range(retries): try: result wait_for(action_func, timeouttimeout) return result except TimeoutError as e: last_error e print(f第 {attempt 1} 次尝试失败剩余 {retries - attempt - 1} 次) time.sleep(2) raise last_error def archive_failed_file(file_path, reason): fail_dir Path(./failures) fail_dir.mkdir(exist_okTrue) dest fail_dir / Path(file_path).name shutil.move(file_path, dest) print(f失败归档: {file_path} - {dest}原因: {reason})重试逻辑里每次间隔2秒是为了给界面留出恢复时间部分卡顿是瞬时抖动两秒后可能就恢复了。归档失败文件比直接删掉更稳妥方便日后复盘或手动补跑。这里有一个设计习惯值得强调脚本宁可在失败时把流程停下来也不要尝试用猜测去处理模糊情况。例如匹配到多个目标无法决定点击哪个时直接归档失败让人来救场八成比自动赌一个要安全。4.3 执行留痕日志、屏幕截图与每步动作证据不用等到出错才后悔不截图。我习惯在每个关键动作后保存一条带时间戳的日志在匹配到目标时顺手截一张全屏图存档。这样一旦流程跑歪可以从截图里回放当时界面到底长什么样。import logging import pyautogui from datetime import datetime logging.basicConfig( filenamerpa_run.log, levellogging.INFO, format%(asctime)s [%(levelname)s] %(message)s ) def log_with_screenshot(step_name): ts datetime.now().strftime(%Y%m%d_%H%M%S) shot_path f./screenshots/{step_name}_{ts}.png pyautogui.screenshot().save(shot_path) logging.info(f步骤 {step_name} 完成截图: {shot_path})每个步骤留一张截图看似占磁盘空间实际上单张PNG截图大约几百KB一天跑几十个步骤也就几十MB完全可接受。留痕的价值在排查问题时才能体现某天早上有三笔单子没处理回看日志和截图能直接定位卡在哪一步是按钮没加载出来还是弹窗挡了道。这比对着屏幕发呆猜原因高效得多。日志级别建议分级记录正常流程打INFO匹配失败打WARNING归档失败打ERROR分析时直接按级别过滤。5. 避坑指南RPAworker跑不起来、跑不稳的五个典型坑5.1 远程桌面会话下鼠标键鼠动作失效现象脚本在本机运行一切正常但放到远程桌面环境里挂着的时候动作执行一会儿就停了pyautogui截图看起来是正常的但点击没有反应。原因锁屏或断开的远程桌面会话里操作系统不会渲染实际的桌面画面。pyautogui的截屏函数拿到的可能是纯色或上一帧的静态图键鼠模拟事件也会被系统丢弃因为桌面已经处于不可交互状态。解决让自动化任务跑在物理机或始终保持活动状态的会话里。如果确实需要远程挂机可以尝试用虚拟显示器或保持远程桌面窗口不被最小化同时设置系统电源计划为“从不休眠”。更稳妥的做法是任务调度器注册成交互式任务保证会话处于激活状态。这是一个硬约束不是靠代码能绕过去的。5.2 屏幕缩放比例不一致导致匹配全偏现象模板匹配在本机分辨率下准确率很高换到同事机器上同一个模板再也找不到或者位置偏了一大截。原因Windows显示设置里缩放比例不同例如一台是100%另一台是125%。pyautogui的截图和坐标基于物理像素如果系统做了缩放拉伸截图实际尺寸和逻辑坐标之间会出现换算偏差模板里记录的像素位置和运行时屏幕内容就不对应了。解决所有运行RPAworker的机器统一显示缩放比例。如果实在无法统一需要把截图分辨率做归一化处理在匹配前将屏幕截图缩放为与模板采集时相同的DPI设定。这个方案能做但复杂最省事还是统一环境。另外注意DPI缩放不要设“自定义”级别预设的100%、125%、150%经过的路径不同模板匹配的偏差模式完全不一样。5.3 中文输入法导致文本输入错乱现象type_text输入中文或混合文本时输入框里出现拼音字母、英文字母甚至触发输入法联想弹窗把后续流程全部打乱。原因pyautogui.write在Windows上通过模拟键盘事件逐字符输入当系统处于中文输入法状态时按键会被输入法拦截并转换为拼音组合而不是直接上屏汉字。解决在输入前切换到英文输入法。常见做法是模拟快捷键切换输入法然后发送一个英文输入事件把状态彻底切到英文模式。如果系统里装了三方输入法快捷键可能不是默认的CtrlSpace需要提前确认。另一个更可靠的方案是改用剪贴板粘贴把文本写入剪贴板然后发送CtrlV完全绕开字符级键盘模拟。import pyperclip import pyautogui def type_text_via_clipboard(text): pyperclip.copy(text) pyautogui.hotkey(ctrl, v)parampyperclip提供跨平台的剪贴板读写接口。这个方案对中文、特殊字符、换行符都友好粘贴操作是一次整体事件不逐字拆解也就不存在输入法干扰的问题。我现在的做法是默认走剪贴板只有目标系统禁止粘贴时才回退到逐字符输入。5.4 按钮是动态渲染的模板匹配峰值忽高忽低现象流程跑了几次之后某个按钮偶尔找不到。人工看截图能清楚看到按钮就在那里但相似度分数就是达不到阈值。原因不少现代网页的按钮有hover、focus、active等状态鼠标经过时颜色会加深、边框会发光。模板里截的是静态灰底按钮运行中按钮正好处于高亮状态或者背景动画恰好挡住了一部分就会导致匹配分数下降。解决模板截取时尽量选按钮的最稳定外观状态例如默认灰色底而不是hover后的高亮色。如果按钮位置固定还可以考虑退而求其次截取按钮旁边的静态文案或区域图标作为锚点因为文案比按钮颜色稳定得多。匹配阈值也不要卡死在0.9给动态渲染留一点余量一般0.8上下比较合理。5.5 杀毒软件拦截键鼠操作或截屏权限现象脚本运行到某个动作时莫名中断有些机器上直接报权限错误有些运行日志什么都没有就停了。原因部分安全软件会把自动化工具模拟的键鼠事件识别为可疑行为直接阻止进程级别的输入注入。截屏操作在某些带数据防泄漏策略的环境下也会被禁止导致pyautogui.screenshot返回黑屏或异常。解决先把脚本加入杀毒软件的白名单尤其是对Python解释器进程和脚本目录放行。如果企业环境有统一安全策略需要IT侧配合开放权限。这个坑不好从代码层面完全绕过如果目标机器安全策略很严需要考虑换一种自动化方式或者把任务放到不受监控的独立环境里跑。遇到权限错误时优先查系统日志里的进程拦截记录比反复调代码效率更高。6. 进阶技巧把固定流程升级成可配置的规则驱动任务前面讲的是把一条流程写死在代码里实际用一段时间后你会发现需求经常变可能是上传按钮的位置变了可能是要处理的文件类型多了一种也可能是填表字段顺序调整了。每次都要改代码并重新部署太麻烦。更实用的做法是把“步骤顺序”和“目标元素模板”拆成配置代码只保留一个通用的执行引擎。做法并不复杂准备一个JSON文件描述流程步骤每一步包含操作类型、模板文件名、输入内容、超时时间这几个字段。执行引擎读取配置后按顺序调用对应动作函数。例如[ {op: open_url, url: http://internal-report.example}, {op: click, template: login_btn.png, confidence: 0.8, timeout: 15}, {op: type, template: username_input.png, text: admin, via_clipboard: true}, {op: type, template: password_input.png, text: ****, via_clipboard: true}, {op: click, template: submit_btn.png}, {op: wait_fixed, seconds: 2}, {op: click, template: upload_area.png}, {op: type, template: file_path_input.png, text: {input_file}, via_clipboard: true}, {op: click, template: confirm_btn.png} ]执行引擎里用一个字典把op名称映射到具体函数再用一个循环顺序处理。这里有个设计要点{input_file}这类占位符在执行时统一替换成本次任务的真实数据这样同一个配置可以反复处理不同文件不需要为每个文件改一行代码。模板文件名指向模板目录下的PNG图片新增界面元素时只需要截一张图放进去不用动代码。这个技巧带来的效果是改流程变成改配置、换模板几行JSON加一张截图就能上线。稳定性上反而比硬编码更好维护因为业务人员自己也能看懂配置里每一步在干什么沟通成本大幅下降。配合第4章的重试与归档机制整个脚本更像是流水线上的一台小设备而不是某一次性的手工脚本。我自己的使用习惯是每个流程至少留一套调试模板和一套运行模板调试模板带明显边框方便肉眼确认匹配位置。配完流程先用一次真实文件小跑看截图日志确认每一步都点对地方再交给定时任务长期跑。长期跑的过程中每周扒一次日志和截图目录观察匹配分数有没有缓慢下降的趋势一旦发现有下滑迹象提前换模板或调阈值比等到跑失败了再救要省心得多。希望这套方案帮到你。本文还有配套的精品资源点击获取