使用 nutjs实现前端RPA需求


theme: qklhk-chocolate
highlight: an-old-hope

前言

上一节,我们先调研了几种实现模拟点击的几种方案,最终我们决定使用 模拟人工手动操作 的方式来实现我们的需求,下面就带着大家来了解下 nutjs

nutjs 相关概念

nut.js 是 Node.js 的桌面自动化框架,我们可以使用 js / ts 来控制鼠标和键盘,来模拟人的操作完成一系列动作。它主要分为以下三块内容:

  • Keyboard
  • Mouse
  • Screen

Keyboard 常用 API

  • type: 它允许我们输入 键 或 字符串:下面我们通过代码 调用 全局搜索框 打开
    `calculator.app。

QQ20221117-185424-HD.gif

代码也比较简单,相信大家也都能看懂,下面给大家看下 Key 里面都有哪些值:

image.png

  • pressKey && releaseKey:两者需要搭配使用,表示 按下不放 –> 释放 的一个过程,联动起来就跟 type 一样了:下面我们通过代码 模拟 command + tab 键 切换应用程序。

    QQ20221118-110223-HD.gif

Mouse 常用 API

它允许通过移动光标、点击鼠标按钮或执行拖动手势来模拟鼠标输入。

下面代码运行效果在屏幕录制时显示不出来鼠标移动,就不能给大家贴图演示了

  • move:控制鼠标移动,我比较常用它里面的入参 有以下几个方法:

    1、straightTo:它接收一个目标点,类似这样:straightTo(new Point(500, 350)),所以 鼠标轨迹也就是从当前位置到目标位置点的直线距离,可以通过 mouse.config.mouseSpeed 设置 鼠标移动的速度:

    const { mouse, straightTo, Point } = require("@nut-tree/nut-js");
    
    (async () => {
      mouse.config.mouseSpeed = 2000;
      const fast = new Point(500, 350);
      await mouse.move(straightTo(fast));
      mouse.config.mouseSpeed = 300;
      const slow = new Point(100, 150);
      await mouse.move(straightTo(slow));
    })();
    
    

    2、left right up down:表示 以当前鼠标位置向【左】【右】【上】【下】移动 x 个像素。

    const { mouse, left, right, up, down } = require("@nut-tree/nut-js");
    
    (async () => {
      await mouse.move(left(500));
      await mouse.move(up(500));
      await mouse.move(right(500));
      await mouse.move(down(500));
    })();
    

    3、click:模拟鼠标的点击,类似这样:await mouse.click(Button.LEFT)

Screen 常用 API

它允许 搜索和等待屏幕上的图像,以验证某些条件,或者进一步使用它们 处理后续逻辑。比如:等目标图片 识别成功后,就可以认为页面已经加载出来了,就可以执行后续的操作了。

  • config 的一些配置:

    1、confidence:指定识别并匹配目标图片的百分比,当设置的值低于匹配值的时候,就意味着匹配成功了,像这样:screen.config.confidence = 0.98 表示匹配度高达 98% 才意味是成功的。

    2、resourceDirectory:可以设置 所要识别目标图片的路径前缀,例如:screen.config.resourceDirectory = "/path/to/my/template/images"

    3、capture && captureRegion :截取当前屏幕保存为截图,两者的区别就是 后者可以设置 截取 的区域;我常把它用在抛出异常或报错后,生成以 报错信息和时间 命名的图片到指定目录,方便我们以后定位排查问题;使用起来也比较简单,这里以 captureRegion 为例:

    QQ20221118-161422-HD.gif

    4、find:查找目标图片,第一个参数就是 调用 imageResource 去解析图片资源,第二个参数是一个配置项 OptionalSearchParameters,里面可以设置 searchRegion, confidence 等参数。

    await mouse.move(straightTo(centerOf(screen.find(imageResource("image.png"), new OptionalSearchParameters(searchRegion, confidence, searchMultipleScales, signal)))))
    

    5、waitFor:和 find 功能相似,它允许我们匹配失败后重试,如下面代码 意思是 失败后 会在 3s 内 每隔 500ms 重试一次,直到 3s 过后才返回匹配结果(成功/失败)

    await mouse.move(straightTo(centerOf(screen.waitFor(imageResource("image.png"), 3000, 500))));
    

    6、highlight:当我们 使用上面方法匹配到目标元素后,可以调用 此方法来显示高亮;可见 匹配度还是比较低的,当 Best match > your config confidence 会匹配失败报错,所以大家在用这块的时候要调好匹配值

    QQ20221118-191715-HD_1.gif

小试牛刀

上面已经介绍了一些常用的API,下面我们实现一个小需求:执行代码打开 备忘录,新建一个备忘录,写入一些文案

这是我们提前准备好要识别的截图,检测成功后便于后续操作

const { screen, keyboard, straightTo, sleep, centerOf, mouse, imageResource, Key } = require("@nut-tree/nut-js");
require("@nut-tree/template-matcher");

(async () => {
  keyboard.config.autoDelayMs = 150;
  screen.config.autoHighlight = true;
  screen.config.highlightDurationMs = 1000; 

  await mouse.move(straightTo(centerOf(screen.waitFor(imageResource("./log/notes.jpg"), 20e3, 5e2))));
  await mouse.leftClick();
  await mouse.move(straightTo(centerOf(screen.waitFor(imageResource("./log/createNote.png"), 20e3, 5e2))));
  await sleep(1e3);
  await mouse.leftClick();
  
  await keyboard.type("今日学习 nutjs 相关知识点") ;
  await keyboard.type(Key.Return);
  
  await keyboard.type("1、screen 相关的API");
  await keyboard.type(Key.Return);
  
  await keyboard.type('2、Mouse 相关API');
  await keyboard.type(Key.Return);
  
  await keyboard.type('3、Keyboard 相关API');
})();

上面代码运行效果如下:

xxx.gif

在这里还想再写一个案例就是自动打开浏览器,使用 百度搜索引擎 搜索相关内容,跟上面代码也比较类似,所以这块就不写了。

最后

上面只是小玩一下,真正开发需求要比这个复杂的多,在错误捕获这块要下很大的功夫,这也是我们在踩坑的😖,下次给大家再分享些。

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容