Python在监控鼠标键盘之后还能做点什么?

594 阅读5分钟

我正在参与掘金创作者训练营第4期,点击了解活动详情,一起学习吧!

前言

首先回答标题

Python在监控鼠标键盘之后,还能做同步播放监控的操作。

想象一下,老板坐在办公室看着你的鼠标一步一步点开掘金,打开本文点了个👍...

Snipaste_2022-02-25_17-07-22.png

需求怎么来的?群众里面有坏人呀,竟然想监控我!👀

咱这是正经儿需求,不是为了监控员工。甲方爸爸要给领导演示操作,展示各种系统功能。

正常情况,这都不是问题,搞个投屏一切OK。但是因为网络,设备等各种问题,甲方爸爸对效果不满意😡。

总之经过各种问题摧残,😭不得不自己想办法实现一下同步操作

终于搞了一个demo出来,本文分享自己的实现思路。

1. 理清思路

做之前先想好要做什么,怎么做。

需求

有两台机器,一台操作机,一台演示机。一台捕捉鼠标键盘,另一台同步动作。

image-20220225150046326.png

小插曲:开始直想同步浏览器操作,但是因为不能移动鼠标,放弃了。

只用js无法实现功能,这时候小学生都在学的Python就出场了。选择他的理由是简单 快速 模块多(关键不会其他的😜)

纪录动作

Python有个库:pyHook能监听鼠标和键盘的动作,用法简单,上手快。

播放动作

Python有个库:PyAutoGUI能控制鼠标键盘动作,非常理想。

纪录和播放的问题解决以后,就差如何通信

要接收和发送信息,理所当然想到了 websocket 通信,Socket.IO 有python模块,并且不能使用websocket的机器上,能t自动转成长轮询。

image-20220225151551832.png

2. 准备工作

💥 注意:本文是在Windows系统下进行的开发,Mac OS不能用。

🚧Python 3

Windows的Python下载

👉 下载地址

pip安装以下库

💡 python 3.* 必须使用PyHook3

# pywin32
# PyHook3
# pyautogui

pip3 install pywin32 PyAutoGUI PyHook3

安装完后使用pip3 list 命令确认

🚧Node.js

Node.js版本 >= 10,除了Node.js 还需要安装 koa2

koa2安装

npm install koa2 -g

都用Python了为什么又要Node.js?

第一版的方案是纯js做动作处理,已经写好了socket.io服务端。🤔咱可是前端,能用js坚决不用其他! 后续继续使用了Node.js

🚧Socket.IO

特别说一下Socket.IO

两台电脑通信需要一台服务器来接收和发送消息

image-20220225154445693.png

因为是做demo就把服务安装在了本地

Socket.IO提供Node.jsPython 的库,使用非常简单

3. 服务端代码

本文仅实现部分鼠标动作,后续会补充完整的代码

包括:纪录端,服务端,播放端都支处理了鼠标移动和单击事件,处理思路是一样的,仅需补充事件即可。

  1. 新建文件夹serve,在文件夹中新建package.json

    {
    	"scripts": {
    		"serve": "node app.js"
    	},
    	"dependencies": {
    		"koa2": "^2.0.0-alpha.7",
    		"socket.io": "^4.4.1"
    	}
    }
    
  2. 初始化项目

    npm i
    
  3. 新建app.js,复制下面的代码,socket.io设置的端口是666

    const Koa = require('koa2');
    const app = new Koa();
    const server = require('http').Server(app.callback());
    const io = require('socket.io')(server, {
      cors: true
    });
    
    const port = 666;
    server.listen(process.env.PORT || port, () => {
      console.log(`app run at : http://127.0.0.1:${port}`);
    })
    
    io.on('connection', socket => {
    
      console.log('加入一个链接');
      socket.on('disconnect', () => {
        console.log('断开一个链接');
      });
    
      socket.on('move', data => {
        console.log('移动到 ' + data);
        socket.broadcast.emit('getMouseMove', data);
      })
      socket.on('click', () => {
        console.log('点击了');
        socket.broadcast.emit('getMouseClick');
      })
    
    })
    
  4. 启动服务端

    npm run serve
    

    运行以后看到输出端口信息

    image-20220225155813535.png

4.客户端代码

新建文件夹client,客户端的代码存放在该目录下面

4.1 纪录机器

👀 代码里仅处理了鼠标移动左键单击,后续补充键盘部分

用PyHook3做鼠标动作监听,通过socketio发送到 ws://127.0.0.1:666(也就是我们服务端的地址和端口)

  1. 新建文件active.py,复制下面的代码

    import socketio
    import pythoncom
    import PyHook3 as pyHook
    
    sio = socketio.Client()
    hm = pyHook.HookManager()
    
    
    @sio.event
    def connect():
        print('链接成功')
    
    
    @sio.event
    def disconnect():
        print('断开链接')
    
    
    @sio.event
    def sendMouseMove(data):
        print('发送鼠标移动', data)
        sio.emit('move', data)
    
    
    @sio.event
    def sendMouseClick():
        print('发送鼠标点击')
        sio.emit('click')
    
    
    # 鼠标事件处理函数
    def OnMouseEvent(event):
        print('MessageName:', event.MessageName)  #事件名称
        print('Message:', event.Message)  #windows消息常量
        # print('Time:', event.Time)  #事件发生的时间戳
        # print('Window:', event.Window)  #窗口句柄
        # print('WindowName:', event.WindowName)  #窗口标题
        # print('Position:', event.Position)  #事件发生时相对于整个屏幕的坐标
        # print('Wheel:', event.Wheel)  #鼠标滚轮
        # print('Injected:', event.Injected)  #判断这个事件是否由程序方式生成,而不是正常的人为触发。
        # print('---')
        position = list(event.Position)
        print('主控端-鼠标')
        sendMouseMove(position)
    
        click = event.Message
        if click == 513:
            sendMouseClick()
        # 返回True代表将事件继续传给其他句柄,为False则停止传递,即被拦截
        return True
    
    
    def start_server():
        sio.connect('ws://127.0.0.1:666')
        # sio.wait()
    
    
    def listenMouse():
        hm.MouseAll = OnMouseEvent
        hm.HookMouse()
        pythoncom.PumpMessages()
    
    
    if __name__ == '__main__':
        start_server()
        listenMouse()
    
    
  2. 运行代码

    py -3 active.py
    

    移动鼠标可以看到输出

    image-20220225160929198.png

    💥 结束监听,需要删除或关闭命令窗口

4.2 播放机器

👀 代码里仅处理了鼠标移动左键单击,后续补充键盘部分

现在一共是两台电脑,3个服务,播放端单独一个,纪录端有两个。

image-20220225161947910.png

用pyautogui重现纪录机器的动作, ws://192.168.137.172:666(也就是我们服务端的地址和端口)

  1. 新建文件passive.py,复制下面的代码

    import pyautogui as pag
    import socketio
    
    sio = socketio.Client()
    
    
    @sio.event
    def connect():
        print('链接成功')
    
    
    @sio.event
    def disconnect():
        print('断开链接')
    
    
    @sio.event()
    def getMouseMove(data):
        print('接收鼠标移动', data)
        x, y = data
        print('移动到', x, y)
        pag.moveTo(x, y, duration=0.1)
    
    
    @sio.event()
    def getMouseClick():
        print('接收鼠标点击')
        pag.click()
    
    
    def start_server():
        sio.connect('ws://192.168.137.172:666')
        # sio.wait()
    
    
    if __name__ == '__main__':
        start_server()
    
    
  2. 运行代码

    py -3 passive.py
    

    💥 结束监听,需要删除或关闭命令窗口

    ✨现在去纪录的机器移动鼠标就能看到效果~~~

最后

文中仅实现鼠标移动和左键单击,提供一下其他的动作文档

👇某CSDN博主的PyHook3 简明教程,文中提到了鼠标钩子,键盘钩子(本文中鼠标纪录也是看的这篇)

blog.csdn.net/q871063970/…

👇找到一份PyAutoGUI的文档,其他动作可以参考

www.bbsmax.com/A/rV57XEbRd…