
就是每天都要重复去点击鼠标, 然后填写那些表格, 这个情况是快让人逼疯的节奏, 那这种问题到底能不能救。每天上班把电脑打开以后, 去点那个一直不变的按钮, 填写那些一模一样的表格再导来导去地弄文件, 这种工作干起来真让人烦心。桌面自动化这东西就是用来解决这类麻烦事的, 它是里面比较实在的一种方案。因为它不靠截图去找图, 也不去靠坐标瞎点, 而是直接去找窗口里面的控件。大多数自动化工具是通过观察屏幕图像来工作的, 如果窗口的位置发生了移动或者是分辨率进行了调整, 那么对应的脚本就会找不到方向而失去作用。另一方面, Web 自动化相关的工具通常只能够针对浏览器进行操作, 一旦遇到桌面客户端就完全无法实现直接的控制和访问。但是选择走控件树这种路线的话就是另外一种情况了, 因为这种方法能够清楚地识别和处理按钮、输入框以及菜单等各类元素, 因此在稳定性的表现方面通常会更好一些。它是一个库, 只能在对应的环境上用。它通过 Win32 API 和 UI API 跟程序打交道。它有两种常用的方式, 一个叫 win32, 一个叫 uia, 选哪种比写多少代码还关键。对于传统的程序框架, 比如 MFC、VB 6、VCL 等老版本工具, 通常情况下, 大家会先去尝试使用 Win32 模式而对于新的框架比如 WPF、UWP 商店应用、Qt 5 以及浏览器这些界面技术, 通常使用 UIA 会更加合适如果要判断应该用哪一种方法, 可以通过提取 .exe 可执行文件, 然后利用 Spy 工具和 UISpy 工具去查看它们的控件树结构, 最后根据观察结果, 选择那个显示内容更完整的方案进行配合操作即可。它的安装过程并不复杂, 前提是你需要有一个合适的环境, 且软件的版本不能过于陈旧。随后执行 pip 命令来完成安装操作也是可行的选择, 当然如果使用的集成开发环境自带安装功能那么直接在 IDE里面进行安装操作也是完全可以的。在完成安装之后建议你通过 pip list 命令行指令或者在代码中尝试 导入的方式来进行查验, 如果能顺利导出的话那基本上就说明已经安装成功了没有出现问题。它有核心的对象有几个。那个东西代表一个应用实例, 可以启动, 也能连接到已经打开的程序。那个地方代表窗口或者对话框, 是用来定位, 等待关闭, 还有做最大化的操作的。然后那里更像一个具体的控件, 能够点击, 能够输入内容, 读取文字, 也能够查看子控件。在定位一个控件的时候, 优先去找到稳定的属性, Class这个属性往往比标题要靠谱一些, 因为标题可能会发生变化, 可以做模糊匹配, 但是不要随便使用, 不然容易点到其他不相关的控件, 等到控件出现的时候也不要依赖sleep这种方式, 能够等待、或者是等待控件准备好, 就尽量使用这些方法。常见的控件包括 Edit、Menu 等等。实际的操作思路都是差不多的, 我们先去看类型, 然后再去查找属性, 接着再决定是使用点击操作还是使用输入文本的操作方式, 这里以记事本作为举例进行说明, 启动或者是连接窗口之后, 我们去定位编辑区, 然后进行文字输入, 接着再走菜单去执行保存这一步骤, 最后还要去处理那个另存为对话框中的逻辑。如果程序已经处于打开的状态, 那么可以通过进程号、标题、类名或者是路径来进行连接操作。在连接成功之后, 去定位登录框、密码框以及按钮这些元素的位置, 然后自动地把信息填写完整, 紧接着再点击相关的按钮完成操作。在进行批量表单处理的时候, 其逻辑和之前的情况是非常类似的不同之处在于, 需要在外层增加一层循环结构, 让数据从表格或者文本文件中进行读取, 最后在提交内容之后还要把结果记录下来。至于导出报表这一项操作, 则必须要多等待一个步骤, 也就是说得一直等到这个文件真正地出现以后再进行最终的校验处理, 一旦发现存在失败的情况就必须重新进行尝试。同时鼠标和键盘这两个模块也都是能够正常使用的, 其中关于鼠标的操作部分可以支持单击动作、双击动作、右键点击以及移动位置和滚轮滚动等多种方式, 需要注意的是其坐标原点的位置是设置在左上角的。键盘主要的输入方式, 是靠那些具体的按键, 其中包括回车键、Tab键、Esc键、退格键、删除键和方向键, 每一个键都有它对应的写法, 至于Ctrl键、Shift键和Alt键呢, 也是可以来进行组合使用的, 但是需要注意的是, 在进行这些操作之前, 最好是能够让当前的目标控件先获取到焦点才行, 而对于那些特殊字符以及中文内容的输入方面, 必须通过实际的测试结果来确认具体是怎么操作的, 绝对不能只是凭自己的主观猜测去认为它会是什么样的情况。但是它并不是什么都能做到的。对于像网页这种不是标准的控件, 或者像是 React 这样的非标准控件来说并不是一定能够直接进行操作的。那些自己画的控件也有可能仅仅显示出一个大的面板来, 在里面什么东西都拆分不出来, 所以首先需要去确认清楚边界在哪里, 然后再决定是不是要使用它去做事情。在开始排查错误的时候, 应该首先去看一下看看选项是不是选错了, 然后接着看控件的加载到底完没完成, 以及层级的查找有没有找对位置, 当发现点击按钮完全没有反应的时候, 这很有可能是焦点丢失了, 或者是窗口被别人挡住遮挡住了, 又或者是按钮本身的状态处于禁用状态了。目标程序使用管理员权限来运行, 脚本也必须进行提权操作。对于中文和特殊字符的情况, 需要通过实测来完成键盘转义工作, 在多显示器的环境下直接采用坐标点击的方式容易出现位置偏移的问题。只要能通过控件方式来完成操作, 就不要采用坐标点击的方法, 因为动态控件非常让人烦恼, 其ID属性以及标题内容都有可能每次运行时都在发生变化。这时候需要换一个更加稳定的属性来进行选择, 或者通过相对位置来找到目标对象。既然进程号并不是固定不变的, 所以应当利用标题、文件路径以及类名这些字段将它们关联起来以完成定位任务。建议在编写的脚本里面专门加入记录日志的功能并进行截图操作, 这样在程序运行失败的时候才能够清楚地知道具体是在哪个步骤卡住的。如果你想让你的代码写得更稳固一点, 那么你可以把窗口和处理界面上的控件封装成类, 这种做法就类似于我们常说的页面对象模式。接下来, 你可以把等待事件、执行点击操作、进行数据输入以及结果校验这样的功能做成公共方法, 从而实现配置文件和核心代码的分离。在程序中一定要加入重试机制, 不过千万不要让它无限次地重试, 你应该为它设置一个具体的上限, 配合适当的超时或者状态检查手段, 这样整个系统就能够被当作回归测试的工具来使用了。它和控件比起来, 那个更加偏向于控件这一层级, 而它自己则是更加偏向于图像以及坐标这些内容。另外把它和网页相关的东西进行比较的话, 它所管理的是桌面程序这种形式的应用软件, 而不是说网页。对于传统的客户端应用程序、ERP企业资源计划系统、还有那些自己研发出来的桌面软件而言, 应当优先考虑使用它而对于Web系统的开发工作, 还是应当采用专门针对Web的工具来处理, 如果在某些混合型的流程场景下, 也可以让两边相互配合来完成相关任务。学习路线不必想得太复杂, 首先进行环境安装, 随后熟悉这类工具的使用, 接着理解元素查找与窗口定位方法, 然后练习控制组件的操作, 最后锻炼鼠标和键盘的交互能力以及开展实战演练, 真正具有难度的地方不在于代码语法本身, 而在于定位技巧以及XPath表达式的选择。先从一个重复性的、小规模的具体场景开始入手, 把那些能够被安排给脚本去执行的部分, 逐步地、缓慢地进行移交。千万不要在刚刚开始的时候就尝试去建立一套庞大且完整的整个流程, 而应该选择先把某一条具体的线路运行成功, 然后再慢慢地去补充关于稳定性的支持以及相关的记录日志工作。