折腾系列之油猴鼠标伴侣,有源文件【python打包的EXE】

6次阅读
没有评论

这个工具只对极小众的朋友有用

作用: 第三方软件调用它实现对鼠标的控制,比如在写油猴脚本时遇到网站采用了阿里无感人机识别时,如果鼠标键盘不动,用户的输入是无法通过的,这就需要油猴调用第三方软件控制鼠标或者键盘做动作。
以前尝试过apache+php+vbs,但它需要电脑安装apache环境和excel(VBS需要调用excel控件才能驱动鼠标)

打包好的EXE 开启后无界面,只在托盘区显示一个黑猫图标,右键点击可退出(仅在自己的电脑WIN11 64上测试过)。

所有文件(python源码,打包配置文件,打包好的EXE)下载地址:

链接:https://pan.baidu.com/s/1i3zbLuSaZX-RqoOX9eCYCA?pwd=ja40
提取码:ja40

使用方法:
# 参数为 click 原地点击
# 参数为 move xd yd 鼠标从当前位置移动
# 参数为 moveTo x y 鼠标移动到目标位置
# 参数为 moveAndClick x y 鼠标移动到目标位置,然后点击
# 参数为 write 要输入的内容 时为模拟键盘输入

cmd 执行举例 :
点击 屏幕上200 200的位置 pymouse.exe click 200 200
js调用执行举例(Jquery):
$.post("http://127.0.0.1:2000", { type: "move", x: 200, y: 100 })
$.get("http://127.0.0.1:2000?type=move&x=200&y=100

还可以添加注册表后在JS中通过 pmouse:\\参数 的方式执行(反应慢,不推荐)

python源代码(我的测试环境 window11 64位 python3.11)
[Asm] 纯文本查看 复制代码

# 需要的依赖
# pip install pyautogui -i https://pypi.tuna.tsinghua.edu.cn/simple/
# pip install pillow
# pip install PyQt5
from PyQt5.QtWidgets import QSystemTrayIcon, QMainWindow, QApplication, QMenu, QAction, QMessageBox
from PyQt5.QtGui import QIcon, QPixmap
import pyautogui
import sys
import os
import socketserver
from http.server import HTTPServer, BaseHTTPRequestHandler
import urllib
import json
from threading import Thread
import socket
import time
import tkinter.messagebox
import ctypes

class TrayModel(QSystemTrayIcon):
def __init__(self, Window):
super(TrayModel, self).__init__()
self.window = Window
self.init_ui()
def init_ui(self):
# 初始化菜单
self.menu = QMenu()
self.quit_action = QAction('退出', self, triggered=self.quit_clock)
self.menu.addAction(self.quit_action)
self.setContextMenu(self.menu)
self.setIcon(QIcon(os.path.dirname(__file__) + '/Pwaerm.ico'))
self.icon = self.MessageIcon()
def quit_clock(self):
stop_thread(webThread)
app.quit()

class HttpHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.deParams(self.path)
def do_POST(self):
params = self.rfile.read(int(
self.headers['content-length'])).decode("utf-8")
self.deParams(params)
def deParams(self, _params):
params = _params.split('&')
try:
args = []
for _key in params:
_v = _key.split("=")
if (len(_v) == 2):
args.append(_v[1])
except:
args = []
self._response(self.path, args)
def _response(self, path, args):
Thread(target=mouseHandler, args=(args,)).start()
result = {"status": 1, "msg": "执行成功"}
# result = mouseHandler(args)
self.send_response(200)
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Content-type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps(result).encode())

def openServer(_port):
httpd = HTTPServer(('', _port), HttpHandler)
httpd.serve_forever()

def mouseHandler(args: list):
print("参数为:", args)
if len(args) > 0:
if args[0] == "click":
# 参数为 click 原地点击
p = pyautogui.position()
pyautogui.click(p.x, p.y)
if args[0] == "clickPoint":
# 参数为 clickPoint x y 点击指定坐标
pyautogui.click(int(args[1]), int(args[2]))
elif args[0] == 'move':
# 参数为 move xd yd 鼠标从当前位置移动
pyautogui.move(int(args[1]), int(args[2]), 0.2)
elif args[0] == 'moveTo':
# 参数为 moveTo x y 鼠标移动到目标位置
pyautogui.moveTo(int(args[1]), int(args[2]), 0.2)
elif args[0] == 'moveAndClick':
# 参数为 moveAndClick x y 鼠标移动到目标位置,然后点击
pyautogui.moveTo(int(args[1]), int(args[2]), 0.5)
pyautogui.click(int(args[1]), int(args[2]))
elif args[0] == 'write':
# 参数为write时为模拟键盘输入
pyautogui.typewrite(args[1], 0.2)
result = {
"status": 1,
"msg": "success"
}
else:
result = {
"status": 0,
"msg": "缺少参数"
}
return result

def net_is_used(port, ip='127.0.0.1'):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((ip, port))
s.shutdown(2)
print('%s:%d is used' % (ip, port))
return True
except:
print('%s:%d is unused' % (ip, port))
return False

class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setFixedSize(300, 200)
self.tray = TrayModel(self)
self.tray.show()

def openServer(_port):
print(_port)
httpd = HTTPServer(('', _port), HttpHandler)
httpd.serve_forever()

def _async_raise(tid, exctype):
"""raises the exception, performs cleanup if needed"""
tid = ctypes.c_long(tid)
if not inspect.isclass(exctype):
exctype = type(exctype)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
tid, ctypes.py_object(exctype))
if res == 0:
raise ValueError("invalid thread id")
elif res != 1:
# """if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"""
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
raise SystemError("PyThreadState_SetAsyncExc failed")

def stop_thread(thread):
_async_raise(thread.ident, SystemExit)

if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.setWindowTitle("P娃儿猫助手v1.0")
window.setFixedSize(200, 160)
# Thread(target=openServer, args=(2000, )).start()
if len(sys.argv[1:]):
mouseHandler(sys.argv[1:])
else:
if not net_is_used(2000):
webThread = Thread(target=openServer, args=(2000, )).start()
window.setWindowIcon(
QIcon(os.path.dirname(__file__) + '/Pwaerm.ico'))
# window.show()
sys.exit(app.exec_())
else:
print("端口已经被占用")
icon = QIcon()
icon.addPixmap(QPixmap(os.path.dirname(__file__) + '/Pwaerm.ico'))
box = QMessageBox()
box.setWindowIcon(icon)
box.setWindowTitle("P娃儿猫提示:")
box.setStandardButtons(QMessageBox.Ok)
box.button(QMessageBox.Ok).setText("确定")
box.setStyleSheet("QLabel{min-width: 260px;min-height:50}")
box.setText("端口已经被占用,程序可能已经启动")
box.exec_()
# tkinter.messagebox.showinfo(title = 'P娃儿猫提示:', message = '端口已经被占用,程序可能已经启动。')

如下代码(JS)示例在百度首页点击 输入框,输入 52pj
浏览器的默认情况下,不允许https页面从http链接引用 javascript/css/plug-ins等资源。启动添加 –allow-running-insecure-content 这一参数会放行这些内容
或者在 edge:\\flags (edge浏览器为例)关闭Block insecure private network requests并重启浏览器即可。

[Asm] 纯文本查看 复制代码

function handlerByPmouse(_type, _x, _y) {
$.get("http://127.0.0.1:2000?type=" + _type + "&x=" + _x + "&y=" + _y);
}
function autoHandler() {
var _node = $("#kw");
console.log(_node);
var x = window.screenLeft;
var y = window.screenTop;
var _p = _node.offset();
var _x = x + _p.left + _node.width() * .2 + Math.random() * _node.width() * .6;
var _y = y + _p.top + 110 + _node.height() * .2 + Math.random() * _node.height() * .6;
handlerByPmouse("moveAndClick", Math.floor(_x), Math.floor(_y));
setTimeout(()=>{
handlerByPmouse("write", "52pj");
},2000);
}
function init() {
autoHandler()
}
if (typeof $ == 'undefined') {
var s = document.createElement("script");
s.onload = init;
s.src = "https://cdn.bootcss.com/jquery/2.1.4/jquery.min.js";
document.getElementsByTagName("HEAD")[0].appendChild(s);
} else {
init();
}

正文完
 0
116博客
版权声明:本篇文章由 116博客 于2024-11-29发表,共计5797字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码