利用Java的Robot工具类控制鼠标及键盘

/ 后端 / 没有评论 / 78浏览

导入鼠标移动依赖,这个是github上找到模仿真人轨迹的鼠标移动 链接

        <dependency>
            <groupId>com.github.joonasvali.naturalmouse</groupId>
            <artifactId>naturalmouse</artifactId>
            <version>2.0.3</version>
        </dependency>

直接上代码

package robot;

import cn.hutool.core.util.RandomUtil;
import com.github.joonasvali.naturalmouse.api.MouseMotionFactory;
import com.github.joonasvali.naturalmouse.util.FactoryTemplates;

import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class RobotTest {

    private Robot robot;

    private MouseMotionFactory currentMotionfactory = null;

    {
        try {
            robot = new Robot();
            robot.delay(500);
        } catch (AWTException e) {
            e.printStackTrace();
        }
    }

    //输入
    private final MousePoint inputPoint = new MousePoint(333, 560, 385, 400);
    //查询
    private final MousePoint searchPoint = new MousePoint(270, 315, 470, 493);
    //展示
    private final MousePoint showPoint = new MousePoint(1000, 1010, 710, 720);
    //复制
    private final MousePoint copyPoint = new MousePoint(950, 965, 710, 720);
    //浏览器外面
    private final MousePoint outPoint = new MousePoint(1264, 1860, 100, 900);
    //当前位置
    private Point currentPoint = new Point(0, 0);

    //错误坐标
    private final List<MousePoint> wrongPointList = Arrays.asList(new MousePoint(560, 900, 450, 530), new MousePoint(272, 1000, 760, 950), new MousePoint(605, 1000, 375, 406));

    //订单号
    private final String orderCode;
    //获取的手机号
    private final Consumer<String> consumer;


    public RobotTest(String orderCode, Consumer<String> consumer) {
        this.orderCode = orderCode;
        this.consumer = consumer;
    }


    public void start() throws InterruptedException {
        //初始位置
        robot.mouseMove(outPoint.minX, outPoint.minY);
        currentPoint.x = outPoint.minX;
        currentPoint.y = outPoint.minY;

        handle();
    }

    private void handle() throws InterruptedException {
        //随机的鼠标动作
        currentMotionfactory = randomMouseMotion();

        //移到输入框
        moveRandom(inputPoint);
        clickOne();

        //输入
        delay(1000);
        inputOrderCode(orderCode);

        //搜索
        delay(1000, 2000);
        randomWrongClick();
        moveRandom(searchPoint);
        clickOne();

        //展示
        delay(1500, 3000);
        randomWrongClick();
        moveRandom(showPoint);
        clickOne();

        //复制
        delay(1500, 3000);
        //randomWrongClick();
        moveRandom(copyPoint);
        clickOne();
        delay(1000, 2000);

        //回到原位置
        moveRandom(outPoint);
        clickOne();
        outputPhone(consumer);
        delay(2000, 4000);
    }

    private MouseMotionFactory randomMouseMotion() {
        int randomInt = RandomUtil.randomInt(100);
        if (randomInt > 90) {
            return FactoryTemplates.createGrannyMotionFactory();
        }
        if (randomInt < 30) {
            return FactoryTemplates.createFastGamerMotionFactory();
        }
        return FactoryTemplates.createAverageComputerUserMotionFactory();
    }

    private void outputPhone(Consumer<String> consumer) {
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        Transferable contents = clipboard.getContents(null);
        try {
            if (contents.isDataFlavorSupported(DataFlavor.stringFlavor)) {
                String text = (String) contents.getTransferData(DataFlavor.stringFlavor);
                consumer.accept(text);
                return;
            }
        } catch (UnsupportedFlavorException | IOException e) {
            e.printStackTrace();
        }
        consumer.accept(null);
    }

    private void randomWrongClick() throws InterruptedException {
        int random = RandomUtil.randomInt(100);
        if (random < 90) {
            return;
        }
        delay(300);
        MousePoint mousePoint = wrongPointList.get(RandomUtil.randomInt(wrongPointList.size()));
        moveRandom(mousePoint);
        clickOne();
    }

    private void inputOrderCode(String orderCode) {
        StringSelection stringSelection = new StringSelection(orderCode);
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        clipboard.setContents(stringSelection, null);
        ctrlV();
    }

    private void moveRandom(MousePoint mousePoint) throws InterruptedException {
        int x = RandomUtil.randomInt(mousePoint.minX, mousePoint.maxX);
        int y = RandomUtil.randomInt(mousePoint.minY, mousePoint.maxY);


        currentMotionfactory.move(x, y);

        currentPoint = MouseInfo.getPointerInfo().getLocation();
        delay(1000);
    }

    private void clickOne() {
        delay(10, 100);
        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
        delay(50, 120);
        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
    }

    private void clickDouble() {
        delay(10, 100);
        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
        delay(50, 120);
        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);

        delay(85, 200);

        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
        delay(50, 120);
        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
    }

    private void ctrlC() {
        delay(10, 100);
        robot.keyPress(KeyEvent.VK_CONTROL);
        delay(200, 350);
        robot.keyPress(KeyEvent.VK_C);
        delay(100, 250);
        robot.keyRelease(KeyEvent.VK_C);
        delay(35, 150);
        robot.keyRelease(KeyEvent.VK_CONTROL);
    }

    private void ctrlV() {
        int random = RandomUtil.randomInt(3);
        if (random == 1) {
            delay(100, 300);
            robot.keyPress(KeyEvent.VK_CONTROL);
            delay(200, 350);
            robot.keyPress(KeyEvent.VK_A);
            delay(100, 250);
            robot.keyRelease(KeyEvent.VK_A);
            delay(35, 150);
            robot.keyRelease(KeyEvent.VK_CONTROL);
        } else {
            clickDouble();
        }

        delay(1000, 2000);

        robot.keyPress(KeyEvent.VK_CONTROL);
        delay(200, 350);
        robot.keyPress(KeyEvent.VK_V);
        delay(100, 250);
        robot.keyRelease(KeyEvent.VK_V);
        delay(35, 150);
        robot.keyRelease(KeyEvent.VK_CONTROL);
    }

    private void delay(int... timeOut) {
        if (timeOut == null || timeOut.length < 1) {
            robot.delay(500);
            return;
        }
        if (timeOut.length > 1) {
            robot.delay(RandomUtil.randomInt(timeOut[0], timeOut[1]));
            return;
        }
        robot.delay(RandomUtil.randomInt(timeOut[0] / 2, timeOut[0]));
    }


    private static class MousePoint {

        public MousePoint(int minX, int maxX, int minY, int maxY) {
            this.minX = minX;
            this.maxX = maxX;
            this.minY = minY;
            this.maxY = maxY;
        }

        private int minX;
        private int maxX;
        private int minY;
        private int maxY;

        public int getMinX() {
            return minX;
        }

        public void setMinX(int minX) {
            this.minX = minX;
        }

        public int getMaxX() {
            return maxX;
        }

        public void setMaxX(int maxX) {
            this.maxX = maxX;
        }

        public int getMinY() {
            return minY;
        }

        public void setMinY(int minY) {
            this.minY = minY;
        }

        public int getMaxY() {
            return maxY;
        }

        public void setMaxY(int maxY) {
            this.maxY = maxY;
        }
    }
}

以下是我测试真实的鼠标点击时间和键盘的监测代码

鼠标点击监测

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>鼠标按下到松开时间监测</title>
</head>
<body>
<div id="test" style="width: 200px; height: 200px; background-color: lightblue;">
  点击并在此区域内按住鼠标,然后松开。
</div>

<script>
  var startTime;
  var testDiv = document.getElementById('test');

  testDiv.addEventListener('mousedown', function(event) {
    startTime = new Date().getTime();
    console.log('鼠标按下时间: ' + startTime);
  });

  testDiv.addEventListener('mouseup', function(event) {
    var endTime = new Date().getTime();
    var duration = endTime - startTime;
    console.log('鼠标松开时间: ' + endTime);
    console.log('鼠标按下到松开的时间: ' + duration + ' 毫秒');
  });
</script>
</body>
</html>

键盘监测

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>键盘按下到松开时间监测</title>
</head>
<body>
<p>请按下并释放键盘上的任意键来测量时间。</p>

<script>
  document.addEventListener('keydown', function(event) {
    var startTime = new Date().getTime();
    console.log('键按下时间: ' + startTime);

    // 存储按下的键和开始时间
    event.target.setAttribute('data-key', event.key);
    event.target.setAttribute('data-start', startTime);
  });

  document.addEventListener('keyup', function(event) {
    var endTime = new Date().getTime();
    var keyPressed = event.target.getAttribute('data-key');
    var startTime = parseInt(event.target.getAttribute('data-start'), 10);
    var duration = endTime - startTime;

    console.log('键 ' + keyPressed + ' 松开时间: ' + endTime);
    console.log('键 ' + keyPressed + ' 按下到松开的时间: ' + duration + ' 毫秒');

    // 清除存储的数据
    event.target.removeAttribute('data-key');
    event.target.removeAttribute('data-start');
  });
</script>
</body>
</html>

鼠标位置打印

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>获取鼠标位置</title>
</head>
<body>

<script>
  let showX,showY;

  document.addEventListener('mousemove', function(event) {
    const x = event.clientX;
    const y = event.clientY;
    //console.log(`鼠标位置: (${x}, ${y})`)
    showX = x;
    showY = y;
  });

  setInterval(()=>{
    console.log(`鼠标位置: (${showX}, ${showY})`)
  },3000)
</script>

</body>
</html>