5分钟,教你做个自动化软件拿来办公、刷副本、回微信 | 源码公开,开箱即用
前两天看到水哥发的这个视频,自己拿来试了试刷副本,强的嘛不谈,但很多功能缺失啊。于是自己花了不少时间重新梳理了一遍。主要是自己拿来玩,所以很多东西不介绍了。如果有对功能感兴趣的盆友,可以b站私信我AbaKir的个人空间_哔哩哔哩_Bilibili
话不多说上代码
主函数很简单,收取了几个输入并且调用类的对象
main.py
from windowsTool import windowsTool, positive_real_num, positive_integer
if __name__ == '__main__':
i1 = positive_real_num(input("匹配图片的置信度:"))
i2 = positive_real_num(input("扫描失败后到下一次扫描等待的时间:"))
i3 = positive_real_num(input("鼠标移动所需要的时间:"))
file_idx = input("文件目录:")
file_idx = None if file_idx == '' else file_idx
run_times = positive_integer(input("选择功能(输入正整数即为运行次数,默认或0为无限次运行):"))
wT = windowsTool(i1, i2, i3, file_idx)
wT(run_times)
精华部分
windowsTool.py
import pyautogui
import time
import xlrd
def positive_real_num(x):
try:
x = float(x)
if x < 0:
x = -x
except:
x = None
return x
def positive_integer(x):
try:
x = int(x)
if x < 0:
x = -x
except:
x = 0
return x
def record_and_print(msg, file_idx):
msg = '[' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + ']: ' + msg + '\n'
print(msg, end='')
with open(file_idx + "history.txt", mode='a', encoding='utf-8') as f:
f.write(msg)
class windowsToolBass:
def __init__(self,
confidence, # 匹配图片的置信度
scan_interval, # 扫描失败后到下一次扫描等待的时间
move_duration, # 鼠标移动所需要的时间
file_idx): # 控制命令文件的地址
self.confidence = confidence
self.scan_interval = scan_interval
self.move_duration = move_duration
self.file_idx = file_idx + '/'
self.cmd_filename = self.file_idx + "cmd.xls"
self.executions_num = 0
self.commands = self._xlrd_read()
record_and_print("数据检查完毕,确认符合基本标准", self.file_idx)
def _move_to_image(self, img):
location = pyautogui.locateCenterOnScreen(self.file_idx + img, confidence=self.confidence)
if location is not None:
pyautogui.moveTo(location, duration=self.move_duration)
return True
else:
return False
def _xlrd_read(self):
# 打开控制命令文件
cmd_file = xlrd.open_workbook(filename=self.cmd_filename).sheet_by_index(0)
# 下面开始对控制命令文件的检查
if cmd_file.nrows < 2: # 行数检查
print("没数据啊哥")
exit(-1)
# 每行数据检查,顺便读取数据
commands = []
i = 1
while i < cmd_file.nrows:
# 第1列 操作类型检查
cmdType = cmd_file.row(i)[0]
if cmdType.ctype != 2 or (cmdType.value not in [float(i) for i in range(1, 10)]):
print('第', i + 1, "行,第1列数据有毛病")
exit(-1)
# 第2列 内容检查
cmdValue = cmd_file.row(i)[1]
# 读图点击类型指令,内容必须为字符串类型
if cmdType.value in [float(i) for i in range(1, 4)] and cmdValue.ctype != 1:
print('第', i + 1, "行,第2列数据有毛病")
exit(-1)
# 输入类型,内容不能为空
if cmdType.value == 4.0 and cmdValue.ctype == 0:
print('第', i + 1, "行,第2列数据有毛病")
exit(-1)
# 等待类型,内容必须为数字
if cmdType.value == 5.0 and cmdValue.ctype != 2:
print('第', i + 1, "行,第2列数据有毛病")
exit(-1)
# 滚轮事件,内容必须为数字
if cmdType.value == 6.0 and cmdValue.ctype != 2:
print('第', i + 1, "行,第2列数据有毛病")
exit(-1)
# 单击事件,内容必须为数字
if cmdType.value == 7.0 and cmdValue.ctype != 2:
print('第', i + 1, "行,第2列数据有毛病")
exit(-1)
# 按下事件,内容必须为键盘内容
if cmdType.value == 8.0 and \
(cmdValue.ctype != 1 or cmdValue.value not in pyautogui.KEYBOARD_KEYS):
print('第', i + 1, "行,第2列数据有毛病")
exit(-1)
# 单击事件,内容必须为数字
if cmdType.value == 9.0 and \
(cmdValue.ctype != 1 or cmdValue.value not in pyautogui.KEYBOARD_KEYS):
print('第', i + 1, "行,第2列数据有毛病")
exit(-1)
# 第3列 重复次数检查
cmdTimes = cmd_file.row(i)[2]
if cmdTimes.ctype != 2 and cmdTimes.ctype != 0:
print('第', i + 1, "行,第3列数据有毛病")
exit(-1)
# 第3列 循环标志检查
loopSwitch = cmd_file.row(i)[3]
if loopSwitch.ctype != 2 and loopSwitch.ctype != 0:
print('第', i + 1, "行,第4列数据有毛病")
exit(-1)
commands.append((cmdType, cmdValue, cmdTimes, loopSwitch))
i += 1
return commands
def _run(self, command):
reTry = -1
if command[2].ctype == 2:
reTry = command[2].value
if command[0].value in [1.0, 2.0, 3.0]:
# 取图片名称
button = 'left' if command[0].value in [1.0, 2.0] else 'right'
button_s = '左' if command[0].value in [1.0, 2.0] else '右'
doubleClick = False if command[0].value in [1.0, 3.0] else True
img_dir = command[1].value
if reTry == -1:
while not self._move_to_image(img_dir):
print("未找到匹配图片", img_dir, ",", self.scan_interval, "秒后重试")
time.sleep(self.scan_interval)
if doubleClick:
record_and_print("鼠标" + button_s + "键双击图片" + img_dir, self.file_idx)
pyautogui.doubleClick(button=button)
else:
record_and_print("鼠标" + button_s + "键单击图片" + img_dir, self.file_idx)
pyautogui.click(button=button)
elif reTry == 0:
if self._move_to_image(img_dir):
if doubleClick:
record_and_print("鼠标" + button_s + "键双击图片" + img_dir, self.file_idx)
pyautogui.doubleClick(button=button)
else:
record_and_print("鼠标" + button_s + "键单击图片" + img_dir, self.file_idx)
pyautogui.click(button=button)
elif reTry > 0:
for i in range(int(reTry)):
if not self._move_to_image(img_dir):
print("第", i + 1, "次重复," + "未找到匹配图片")
else:
if doubleClick:
record_and_print("鼠标" + button_s + "键双击图片" + img_dir, self.file_idx)
pyautogui.doubleClick(button=button)
else:
record_and_print("鼠标" + button_s + "键单击图片" + img_dir, self.file_idx)
pyautogui.click(button=button)
break
elif reTry == -2:
while self._move_to_image(img_dir):
if doubleClick:
record_and_print("鼠标" + button_s + "键双击图片" + img_dir, self.file_idx)
pyautogui.doubleClick(button=button)
else:
record_and_print("鼠标" + button_s + "键单击图片" + img_dir, self.file_idx)
pyautogui.click(button=button)
time.sleep(0.2)
elif command[0].value == 4.0:
record_and_print("输入:" + str(command[1].value), self.file_idx)
pyautogui.typewrite(command[1].value)
elif command[0].value == 5.0:
record_and_print("等待" + str(command[1].value) + "秒", self.file_idx)
time.sleep(command[1].value)
elif command[0].value == 6.0:
record_and_print("滚轮滚动" + str(int(command[1].value)) + "个单位", self.file_idx)
pyautogui.scroll(int(command[1].value))
elif command[0].value == 7.0:
button = 'left' if command[1].value == 1.0 else 'right'
button_s = '左' if command[1].value == 1.0 else '右'
record_and_print("鼠标" + button_s + "键单击", self.file_idx)
elif command[0].value == 8.0:
record_and_print("按下" + str(command[1].value) + "键", self.file_idx)
pyautogui.keyDown(command[1].value)
elif command[0].value == 9.0:
record_and_print("松开" + str(command[1].value) + "键", self.file_idx)
pyautogui.keyUp(command[1].value)
class windowsTool(windowsToolBass):
def __init__(self,
confidence,
scan_interval,
move_duration,
file_idx):
if confidence is None:
confidence = 0.95
if scan_interval is None:
scan_interval = 1
if move_duration is None:
move_duration = 0.1
if file_idx is None:
file_idx = "./"
super().__init__(confidence, scan_interval, move_duration, file_idx)
def __call__(self, n):
while n != 1:
n -= 1
record_and_print("开始第" + str(self.executions_num + 1) + "次执行", self.file_idx)
self.executions_num += 1
cycle = []
for idx, command in enumerate(self.commands):
if command[3].ctype == 2:
cycle.append((idx, int(command[3].value)))
if len(cycle) != 0:
num_cycle = cycle[0][1]
idx_cycle = cycle[0][0]
else:
num_cycle = 1
idx_cycle = -1
for idx, command in enumerate(self.commands):
if idx == idx_cycle:
while num_cycle != 1:
for command_cycle in self.commands[cycle[0][0]:cycle[1][0] + 1]:
self._run(command_cycle)
num_cycle -= 1
self._run(command)
cmd.xls