• python写的 自定义连点器 的开发全过程(抢票、信息轰炸等、游戏连招等)——思路及解析【内附完整源码】


    前些天留意到我妈一直在预约四价疫苗都约不上,就想着写个程序来模拟人的操作去点击,判断疫苗是否被抢完,无限循环去刷新这个页面,一旦疫苗可预约就立马抢下来选择时间接种人。当预约成功后就语音循环播报:已经抢到,赶紧过来看一下。

    基于以上的想法和需求,我花了半小时编辑了以下代码,并在一小时内成功预约。

    1. import pyautogui
    2. from ctypes import * # 获取屏幕上某个坐标的颜色
    3. from time import sleep
    4. import time
    5. start = time.time()
    6. def get_color(x, y):
    7. gdi32 = windll.gdi32
    8. user32 = windll.user32
    9. hdc = user32.GetDC(None) # 获取颜色值
    10. pixel = gdi32.GetPixel(hdc, x, y) # 提取RGB值
    11. r = pixel & 0x0000ff
    12. g = (pixel & 0x00ff00) >> 8
    13. b = pixel >> 16
    14. return [r, g, b]
    15. print(get_color(297,454))
    16. while True:
    17. if get_color(240 , 255) == [60,211,180] or get_color(247,255) == [60,211,180] or get_color(253,255) == [60,211,180] or get_color(260,255) == [60,211,180] or get_color(270,255) == [60,211,180] or get_color(280,255) == [60,211,180] or get_color(290 ,255) == [60,211,180] or get_color(300 ,255) == [60,211,180] or get_color(310,255) == [60,211,180] or get_color(320, 255) == [60,211,180]:
    18. pyautogui.click(310,255)#点进去抢
    19. sleep(0.5)
    20. pyautogui.click(467,262)#选择预约时间
    21. while True:
    22. if get_color(297,454) == [0,142,255]:
    23. break
    24. else:
    25. sleep(0.3)
    26. sleep(0.5)
    27. pyautogui.click(498,454)#点击下午
    28. sleep(0.5)
    29. pyautogui.click(467,520)#选择时间
    30. sleep(0.5)
    31. pyautogui.click(470,899)#点选好了
    32. sleep(0.5)
    33. pyautogui.click(470, 899)#点立即预约
    34. #sleep()
    35. break
    36. else:
    37. pyautogui.click(123,60)
    38. sleep(0.8)#刷新
    39. print('总耗时:'.format(time.time()-start))
    40. print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
    41. while 1:
    42. import pyttsx3
    43. engine = pyttsx3.init()
    44. engine.say('我抢到了!快来看一下')
    45. engine.runAndWait()
    46. sleep(1)

    实现思路大致流程图:

    可以看到逻辑非常简单即可实现我想要的功能,不过即使是这样,我也花了差不多半小时的时间来编写代码。于是我就在想,要是以后我要开发抢票、技能连招啊、信息轰炸朋友啊等等的功能,是不是也要这么多时间呢,那我能不能自己造轮子来快速帮助我开发我想要的脚本呢。

    至此,此章的内容正式开始了。

    我将一步一步带着读者来开发这个快速开发自定义连点器的程序(有一点点拗口)

    目录

    整体思路:

    所有功能

    简单演示

    点击功能

     点击功能代码如下:

    执行时的逻辑:

    延时功能

    执行时的逻辑: 

    连点功能

    执行时的逻辑:

    存储功能

    读取功能

    存储导入功能【升级版】

    导入(功能实现)

    导入(逻辑代码)

    存储(功能实现)

    存储(逻辑代码) 

    拖拽功能

    功能实现

    逻辑代码:

    功能实现

     逻辑代码

    右击、中击、双击功能的实现

    功能实现

    逻辑代码

    按键功能

    功能实现

    逻辑代码

    滚动滚轮功能

    功能实现

    逻辑代码

    查看功能

     执行功能

    逻辑判断功能板块

    判断功能

    判断功能的逻辑代码

     逻辑执行功能的实现

    逻辑块存储功能的实现

    逻辑块存储逻辑代码

    逻辑块导入功能的实现

    完整代码


    整体思路:

    一般需要的功能有:点击、延时、连点、拖拽。一般这四个功能就能完成绝大多数的简单的辅助脚本开发了,但我想做得稍微高级一点,功能多一点,就想另外开发:循环、判断、模拟按键、文本输入、存储操作、读取操作的功能。

    那么我们就要朝着我们想要实现的九大功能来开发:循环、点击、延时、连点、拖拽、判断、模拟按键、文本输入、存储操作、读取操作。

    首先就是希望我的每一步操作都会被程序记录下来并执行,我们可以定义一个列表来存储每一个操作,列表中的每一个元素就是每一步的操作,然后遍历这个列表来读取并执行每一个操作就可以将一整个操作全部执行。

    当我的每一步操作都输入完毕后,我都希望程序能自动帮我把程序存储下来方便我下一次使用,这样下次使用就不用再编译多一次了。

    每一个列表的第0项就是需要操作的功能,第0项之后都是各种参数。

    所有功能

    简单演示

      

    点击功能

    要想电脑帮我们点击,首先要告诉电脑我要点击的位置在哪里。想要获取鼠标位置就需要用到pyautogui库,这个库下有个position()方法可以返回鼠标位置的X坐标,Y坐标。

    也可以参考一下我之前的文章:实时获取鼠标位置_晋升阁的博客-CSDN博客_实时显示鼠标坐标

    定义获取位置函数

    1. import pyautogui
    2. def get_xy():
    3. x, y = pyautogui.position()
    4. return [x,y]

    用面向对象思想来简化程序,提高代码复用率,使程序可读性更高,是python开发的重要思想之一哦

    pyautogui库还有非常多常见功能,感兴趣的可以翻看我之前写的博客:像selenium一样操作电脑,保姆式教学——速成篇_晋升阁的博客-CSDN博客

     点击功能代码如下

    1. step=[]
    2. while True:
    3. choose = input('请输入你需要使用的功能:')
    4. if choose == '点击':
    5. click = []
    6. while 1:
    7. click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
    8. if click_dongzuo == '1':
    9. click_weizhi = get_xy()
    10. click.append('点击')
    11. click.append(click_weizhi)
    12. step.append(click)
    13. break
    14. elif click_dongzuo == '0':
    15. print('操作已取消')
    16. break
    17. else:
    18. print('请输入正确的操作(输入“0”或“1”')

    执行时的逻辑:

    1. for i in step1:
    2. if i[0] == '点击':
    3. x = int(i[1][0])
    4. y = int(i[1][1])
    5. print(f'{x},{y}')
    6. pyautogui.click(x,y)

    记录点击需要记录点击功能、位置参数生成一个列表,然后将列表append到step总列表中去

    延时功能

    使用到了python内置库中的time模块,可以使程序强制停止相应时间。将参数生成列表append到step总列表中去

    1. if choose =='延时':
    2. while 1:
    3. timerr = []
    4. try:
    5. timex = int(input('请输入延时时间:'))
    6. timerr.append('延时')
    7. timerr.append(timex)
    8. step.append(timerr)
    9. break
    10. except:
    11. print('延时失败/n请输入正确的延时时间')
    12. continue

    执行时的逻辑: 

    1. def timer(timex):
    2. time.sleep(timex)
    3. if i[0] == '延时':
    4. t = int(i[1])
    5. timer(t)

    连点功能

     有些简单的页面可以通过连点来实现抢票等功能,这个功能必不可少

    记录这个动作的必要参数有连点功能记录、点击频率参数、通过连点次数完成动作还是通过连点时长完成动作。

    同样是调用了获取鼠标位置的函数,

    1. if choose == '连点':
    2. click_liandian = []
    3. while 1:
    4. click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
    5. if click_dongzuo == '1':
    6. click_weizhi = get_xy()
    7. click_liandian.append('连点')
    8. click_liandian.append(click_weizhi)
    9. break
    10. elif click_dongzuo == '0':
    11. print('操作已取消')
    12. break
    13. else:
    14. print('请输入正确的操作(输入“0”或“1”')
    15. click_pinlv = float(input('请输入连点频率:'))
    16. while 1:
    17. click_stop_choose = input('“连点次数”or“连点时长”')
    18. if click_stop_choose =='连点次数':
    19. click_cishu = int(input('请输入连点次数:'))
    20. click_liandian.append('连点次数')
    21. click_liandian.append(click_cishu)
    22. click_liandian.append(click_pinlv)
    23. step.append(click_liandian)
    24. print(click_liandian)
    25. print(step)
    26. break
    27. if click_stop_choose == '连点时长':
    28. click_shichang = int(input('请输入连点时长(秒):'))
    29. click_liandian.append('连点时长')
    30. click_liandian.append(click_shichang)
    31. step.append(click_liandian)
    32. click_liandian.append(click_pinlv)
    33. print(click_liandian)
    34. print(step)
    35. break
    36. else:
    37. continue

    执行时的逻辑:

    1. if choose == '连点':
    2. click_liandian = []
    3. while 1:
    4. click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
    5. if click_dongzuo == '1':
    6. click_weizhi = get_xy()
    7. click_liandian.append('连点')
    8. click_liandian.append(click_weizhi)
    9. break
    10. elif click_dongzuo == '0':
    11. print('操作已取消')
    12. break
    13. else:
    14. print('请输入正确的操作(输入“0”或“1”')
    15. click_pinlv = float(input('请输入连点频率:'))
    16. while 1:
    17. click_stop_choose = input('“连点次数”or“连点时长”')
    18. if click_stop_choose =='连点次数':
    19. click_cishu = int(input('请输入连点次数:'))
    20. click_liandian.append('连点次数')
    21. click_liandian.append(click_cishu)
    22. click_liandian.append(click_pinlv)
    23. step.append(click_liandian)
    24. print(click_liandian)
    25. print(step)
    26. break
    27. if click_stop_choose == '连点时长':
    28. click_shichang = int(input('请输入连点时长(秒):'))
    29. click_liandian.append('连点时长')
    30. click_liandian.append(click_shichang)
    31. step.append(click_liandian)
    32. click_liandian.append(click_pinlv)
    33. print(click_liandian)
    34. print(step)
    35. break
    36. else:
    37. continue

    存储功能

    当我们记录完所有操作后我们希望将操作保存下来方便下次使用,不需要从头录入。

    这将生成一个与py脚本同级的txt文件,txt文件中保存了所有的步骤,可直接读取使用

    1. if choose =='存储':
    2. if len(step) == 0:
    3. print('还未记录你任何操作,请添加操作再使用存储功能')
    4. else:
    5. do_name = input('请为以上操作命名吧:')
    6. path = r"{}.txt".format(do_name)
    7. with open(path, "w",encoding = 'utf8') as f:
    8. f.write(str(step))

    读取功能

    这一步呢就稍微麻烦一点,因为txt没办法记录list类型的数据,只能以str类型写出去并且只能以str类型读取进来。我自己定义了一些函数来转化为list类型,比较复杂,就不再说明函数是怎么实现的,日后有机会再跟各位分享。

    1. def writeList2txt(file,data):
    2. '''
    3. 将list写入txt
    4. :param data:
    5. :return:
    6. '''
    7. file.write(str(data))
    8. def readListFromStr(str):
    9. '''
    10. str -> List
    11. 除去冗余的方法调用
    12. :param str:
    13. :return:
    14. '''
    15. res,pos = help(str,1)
    16. res1=[]
    17. a ='1'
    18. for ii in res:
    19. iii=[]
    20. for i in ii:
    21. if type(i)==type(a):
    22. i = i.replace("'", "")
    23. iii.append(i)
    24. else:
    25. iii.append(i)
    26. res1.append(iii)
    27. return res1
    28. def help(str,startIndex):
    29. '''
    30. 单行字符串的读取,形成list
    31. :param str:
    32. :return:
    33. '''
    34. str = str.replace(" ","") # 将所有空格删去
    35. res = []
    36. i = startIndex
    37. pre = startIndex
    38. while i <len(str):
    39. if str[i] == '[':
    40. # 将pre-i-2的字符都切片,切split
    41. if i-2>=pre:
    42. slice = str[pre:i-1].split(',')
    43. for element in slice:
    44. res.append(element)
    45. # 递归调用 加入子list
    46. child,pos = help(str,i+1)
    47. res.append(child)
    48. i = pos # i移动到pos位置,也就是递归的最后一个右括号
    49. pre = pos + 2 # 右括号之后是, [ 有三个字符,所以要+2至少
    50. elif str[i] == ']':
    51. # 将前面的全部放入列表
    52. if i-1>=pre:
    53. slice = str[pre:i].split(',')
    54. for element in slice:
    55. res.append(element)
    56. return res,i
    57. i = i + 1
    58. return res,i
    59. def get_caozuo(caozuopath):
    60. with open(caozuopath , 'r' , encoding='utf8') as f:
    61. data = f.read()
    62. return data
    63. def get_caozuo_name():
    64. files1 = []
    65. file_dir = r"C:\Users\ge\Desktop\test1\我的作品\自定义连点器"
    66. for root, dirs, files in os.walk(file_dir, topdown=False):
    67. files = files[:-1]
    68. for i in files:
    69. files1.append(i[:-4])
    70. return files1
    71. print(get_caozuo_name())
    72. if choose == '循环执行':
    73. caozuojiyi = get_caozuo_name()
    74. while True:
    75. xunhuan_choose = input('已存储的操作有:{}\n请输入循环操作的操作名:'.format(caozuojiyi))
    76. if xunhuan_choose in caozuojiyi:
    77. break
    78. else:
    79. print('存储库中并无你想要的操作,请重新输入:')

    存储导入功能【升级版】

    上面的功能只能把二维的列表导入成list类型的数据类型,不利于后面的导入。一旦存储或导入的列表达到三维或以上就不适用了。后来我在网上搜了半天,终于发现json库里面有方法支持以list的形式导出txt并且可以以list的方式读取。以下是我实现存储导入的逻辑代码:

    导入(功能实现)

    1. def txttolist(path):
    2. import json
    3. b = open(path, "r", encoding='UTF-8')
    4. out = b.read()
    5. out = json.loads(out)
    6. return out

    导入(逻辑代码)

    如果程序内存里已有操作了将提示保存

    1. if choose == '导入':
    2. if len(step) == 0:
    3. step = daoru()[0]
    4. else:
    5. baocun_choose = input('此次操作若未保存请先,导入别的操作会覆盖原来的操作,你确定要导入吗?\n请输入“yes”or“no”:\n')
    6. while 1:
    7. if baocun_choose == 'no':
    8. break
    9. if baocun_choose == 'yes':
    10. print('你已取消保存')
    11. step = daoru()[0]
    12. break
    13. else:
    14. yorn = input("请输入'yes'or'no':\n")

    存储(功能实现)

    1. def cunchu():
    2. yorn = input("执行完毕,是否保存?\n输入'yes'or'no'\n")
    3. while 1:
    4. if yorn == 'yes':
    5. if len(step) == 0:
    6. print('还未记录你任何操作,请添加操作再使用存储功能')
    7. else:
    8. do_name = input('请为以上操作命名吧:')
    9. path = r"{}.txt".format(do_name)
    10. listtotxt(list=step, path=path)
    11. break
    12. if yorn == 'no':
    13. print('你已取消存储')
    14. break
    15. else:
    16. yorn = input("请输入'yes'or'no':\n")
    17. def listtotxt(list, path):
    18. import json
    19. c_list = list
    20. c_list = json.dumps(c_list)
    21. '''将c_list存入文件
    22. '''
    23. a = open(path, "w", encoding='UTF-8')
    24. a.write(c_list)
    25. a.close()
    26. print('已存入txt')

    存储(逻辑代码) 

    要是程序内存里还没有操作将提醒

    1. if choose == '存储':
    2. if len(step) == 0:
    3. print('还未记录你任何操作,请添加操作再使用存储功能')
    4. else:
    5. do_name = input('请为以上操作命名吧:')
    6. path = r"{}.txt".format(do_name)
    7. listtotxt(list=step, path=path)

    拖拽功能

    这个功能也是基于pyautogui库来使用的,主要用到了pyautogui.dragTo()方法

    功能实现

    1. pyautogui.moveTo(int(i[1][0]), int(i[1][1]))
    2. pyautogui.dragTo(int(i[2][0]), int(i[2][1]), 1, button='left')
    3. print(f'已执行拖拽动作,拖拽起始位置是X:{int(i[1][0])},Y:{int(i[1][1])},拖拽后的位置是X:{int(i[2][0])},Y:{int(i[2][1])}')

    逻辑代码:

    先创建列表tuozhuai,向列表添加三个参数:“拖拽”、第一个位置参数、第二个位置参数

    1. if choose == '拖拽':
    2. tuozhuai = []
    3. while 1:
    4. click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成移动前的位置输入,输入“0”取消动作')
    5. if click_dongzuo == '1':
    6. click_weizhi = get_xy()
    7. tuozhuai.append('拖拽')
    8. tuozhuai.append(click_weizhi)
    9. while 1:
    10. click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成移动后的位置输入,输入“0”取消动作')
    11. if click_dongzuo == '1':
    12. click_weizhi = get_xy()
    13. tuozhuai.append(click_weizhi)
    14. break
    15. elif click_dongzuo == '0':
    16. print('操作已取消')
    17. break
    18. else:
    19. print('请输入正确的操作(输入“0”或“1”')
    20. break
    21. elif click_dongzuo == '0':
    22. print('操作已取消')
    23. break
    24. else:
    25. print('请输入正确的操作(输入“0”或“1”')
    26. step.append(tuozhuai)

    也是用到了pyauogui库,主要使用pyautogui库的pytewrite函数,但是这个函数对中文不友好,于是我另辟蹊径使用pyperclip库的copy函数将要输入的文本内容拷贝打粘贴板,通过控制按键control+v来输入至目标位置。

    功能实现

    1. if choose == '输入':
    2. shuru = []
    3. while 1:
    4. click_dongzuo = input('请移动鼠标到你要输入的位置上输入“1”完成动作,输入“0”取消动作')
    5. if click_dongzuo == '1':
    6. click_weizhi = get_xy()
    7. txt_in = input('请输入你要在该位置输入的文字:\n')
    8. shuru.append('输入')
    9. shuru.append(click_weizhi)
    10. shuru.append(txt_in)
    11. step.append(shuru)
    12. break
    13. elif click_dongzuo == '0':
    14. print('操作已取消')
    15. break
    16. else:
    17. print('请输入正确的操作(输入“0”或“1”')

     逻辑代码

    1. if i[0] == '输入':
    2. pyautogui.click(int(i[1][0]), int(i[1][1]))
    3. pyperclip.copy(i[2])
    4. time.sleep(0.1)
    5. pyautogui.hotkey('ctrl', 'v')

    右击、中击、双击功能的实现

    原理相同,将不再赘述

    功能实现

    1. if i[0] == '双击':
    2. pyautogui.click(int(i[1][0]), int(i[1][1]))
    3. pyautogui.click(int(i[1][0]), int(i[1][1]))
    4. print(f'已执行完点击动作,点击坐标位置:X:{int(i[1][0])},Y:{int(i[1][1])} ')
    5. if i[0] == '右击':
    6. x = int(i[1][0])
    7. y = int(i[1][1])
    8. pyautogui.rightClick(x, y)
    9. print(f'已执行完右击动作,点击坐标位置:X:{x},Y:{y} ')
    10. if i[0] == '中击':
    11. x = int(i[1][0])
    12. y = int(i[1][1])
    13. pyautogui.middleClick(x, y)
    14. print(f'已执行完中击动作,点击坐标位置:X:{x},Y:{y} ')

    逻辑代码

    1. if choose == '右击':
    2. click_r = []
    3. while 1:
    4. click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
    5. if click_dongzuo == '1':
    6. click_weizhi = get_xy()
    7. click_r.append('右击')
    8. click_r.append(click_weizhi)
    9. step.append(click_r)
    10. break
    11. elif click_dongzuo == '0':
    12. print('操作已取消')
    13. break
    14. else:
    15. print('请输入正确的操作(输入“0”或“1”')
    16. if choose == '中击':
    17. click_m = []
    18. while 1:
    19. click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
    20. if click_dongzuo == '1':
    21. click_weizhi = get_xy()
    22. click_m.append('中击')
    23. click_m.append(click_weizhi)
    24. step.append(click_m)
    25. break
    26. elif click_dongzuo == '0':
    27. print('操作已取消')
    28. break
    29. else:
    30. print('请输入正确的操作(输入“0”或“1”')
    31. click_double = []
    32. while 1:
    33. click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
    34. if click_dongzuo == '1':
    35. click_weizhi = get_xy()
    36. click_double.append('双击')
    37. click_double.append(click_weizhi)
    38. step.append(click_double)
    39. break
    40. elif click_dongzuo == '0':
    41. print('操作已取消')
    42. break
    43. else:
    44. print('请输入正确的操作(输入“0”或“1”')

    按键功能

    功能实现

    1. if i[0] == '按键':
    2. pyautogui.hotkey(*i[1])

    逻辑代码

    1. if choose == '按键':
    2. while 1:
    3. anjian = input('这是模拟操作键盘的操作(例如复制,输入’ctrl‘ + ’c‘):\n')
    4. if anjian != 'q':
    5. anjian = anjian.split('+')
    6. anjians = []
    7. a = []
    8. for an in anjian:
    9. an = an.replace("‘", "").replace("’", "").strip()
    10. if an in pyautogui.KEYBOARD_KEYS:
    11. anjians.append(an)
    12. nihaofan = 0
    13. else:
    14. print('你的输入不合法')
    15. nihaofan = 1
    16. break
    17. if nihaofan == 0:
    18. a.append('按键')
    19. a.append(anjians)
    20. step.append(a)
    21. print('录入成功')
    22. break
    23. if anjian == 'q':
    24. break

    滚动滚轮功能

    功能实现

    1. if i[0] == '滚动':
    2. import pywinauto.mouse
    3. x, y = pyautogui.position()
    4. pywinauto.mouse.scroll((x, y), i[1]) # (1100,300)是初始坐标,1000是滑动距离(可负)

    逻辑代码

    1. if choose == '滚动':
    2. while 1:
    3. gundong = []
    4. try:
    5. gundong1 = int(input('这里是模拟鼠标滚动,请输入你要滚动距离(正数为向上移动,负数为向下移动):\n'))
    6. gundong.append('滚动')
    7. gundong.append(gundong1)
    8. step.append(gundong)
    9. break
    10. except:
    11. print('你的输入有误,请重新输入')

    查看功能

    1. def chakan():
    2. if len(step) == 0:
    3. print('暂未录入操作,请先录入操作再查看')
    4. zizeng = 1
    5. for i in step:
    6. if i[0] == '点击':
    7. x = int(i[1][0])
    8. y = int(i[1][1])
    9. print(f'第{zizeng}步:\n执行点击动作,点击坐标位置:X:{x},Y:{y} ')
    10. if i[0] == '延时':
    11. t = int(i[1])
    12. print(f'第{zizeng}步:\n执行延时动作,延时时长:{t}秒')
    13. if i[0] == '连点':
    14. if i[2] == '连点次数':
    15. print(f'第{zizeng}步:\n执行连点操作,你选择的是{i[2]},连点次数是{i[4]}')
    16. if i[2] == '连点时长':
    17. print(f'第{zizeng}步:\n执行连点操作,你选择的是{i[2]},连点时长是{i[4]}秒')
    18. if i[0] == '拖拽':
    19. print(
    20. f'第{zizeng}步:\n执行拖拽动作,拖拽起始位置是X:{int(i[1][0])},Y:{int(i[1][1])},拖拽后的位置是X:{int(i[2][0])},Y:{int(i[2][1])}')
    21. if i[0] == '双击':
    22. print(f'第{zizeng}步:\n执行点击动作,点击坐标位置:X:{int(i[1][0])},Y:{int(i[1][1])} ')
    23. if i[0] == '按键':
    24. print(f'第{zizeng}步:\n执行按键动作,将同时按下”{i[1]}“键')
    25. zizeng += 1

     执行功能

    执行后将询问是否保存

    1. def zhixing(step):
    2. for i in step:
    3. if i[0] == '点击':
    4. x = int(i[1][0])
    5. y = int(i[1][1])
    6. pyautogui.click(x, y)
    7. print(f'已执行完点击动作,点击坐标位置:X:{x},Y:{y} ')
    8. if i[0] == '延时':
    9. t = int(i[1])
    10. timer(t)
    11. print(f'已执行完延时动作,延时时长:{t}秒')
    12. if i[0] == '连点':
    13. if i[2] == '连点次数':
    14. clicker_cishu(int(i[3]), int(i[1][0]), int(i[1][1]), int(i[4]))
    15. print(f'已执行完连点操作,你选择的是{i[2]},连点次数是{i[4]}')
    16. if i[2] == '连点时长':
    17. clicker_time(int(i[3]), int(i[1][0]), int(i[1][1]), int(i[4]))
    18. print(f'已执行完连点操作,你选择的是{i[2]},连点时长是{i[4]}秒')
    19. if i[0] == '拖拽':
    20. pyautogui.moveTo(int(i[1][0]), int(i[1][1]))
    21. pyautogui.dragTo(int(i[2][0]), int(i[2][1]), 1, button='left')
    22. print(f'已执行拖拽动作,拖拽起始位置是X:{int(i[1][0])},Y:{int(i[1][1])},拖拽后的位置是X:{int(i[2][0])},Y:{int(i[2][1])}')
    23. if i[0] == '双击':
    24. pyautogui.click(int(i[1][0]), int(i[1][1]))
    25. pyautogui.click(int(i[1][0]), int(i[1][1]))
    26. print(f'已执行完点击动作,点击坐标位置:X:{int(i[1][0])},Y:{int(i[1][1])} ')
    27. if i[0] == '输入':
    28. pyautogui.click(int(i[1][0]), int(i[1][1]))
    29. pyperclip.copy(i[2])
    30. time.sleep(0.1)
    31. pyautogui.hotkey('ctrl', 'v')
    32. if i[0] == '按键':
    33. pyautogui.hotkey(*i[1])
    34. if i[0] == '右击':
    35. x = int(i[1][0])
    36. y = int(i[1][1])
    37. pyautogui.rightClick(x, y)
    38. print(f'已执行完右击动作,点击坐标位置:X:{x},Y:{y} ')
    39. if i[0] == '中击':
    40. x = int(i[1][0])
    41. y = int(i[1][1])
    42. pyautogui.middleClick(x, y)
    43. print(f'已执行完中击动作,点击坐标位置:X:{x},Y:{y} ')
    44. if i[0] == '滚动':
    45. import pywinauto.mouse
    46. x, y = pyautogui.position()
    47. pywinauto.mouse.scroll((x, y), i[1]) # (1100,300)是初始坐标,1000是滑动距离(可负)
    1. if choose == '执行':
    2. if len(step) == 0:
    3. print('你还未记录任何操作,请至少记录了一个操作再执行')
    4. else:
    5. zhixing(step)
    6. cunchu()

    逻辑判断功能板块

    到了最难最虐脑的逻辑判断功能了,逻辑判断板块这几个功能困扰了我一整天,敲到我脑壳疼

    判断功能

    实现这一功能主要是基于颜色的RBG值来判断程序所要要执行的步骤块。

    选择目标点,开启线程去时刻监管这个目标点的颜色变化,一旦目标颜色变为期待值,立即执行之前存储的步骤块,可以选择是否循环这个步骤块的操作。选择完毕后开启第二个线程去执行这个步骤块,此时主程序将继续遍历panduans的操作。设置一个while循环来阻塞主程序的运行及监控state变量值的变化,state初始值为“未触发”,一旦监管线程发现目标值变化为期待值,立即修改state值为“触发”,同时关闭执行步骤块的线程,同时关闭自身的监管线程,此时主程序检测到state值为“触发”后立刻将新的步骤块的线程开启并将state值修改为“未触发”。就此开启新一轮的循环。

    之间呢,遇到了多个线程修改同一个值的情况导致报错;遇到了多种停止线程的方法都不适用的情况;遇到了没设置守护进程又要找到这个进程去关闭的情况;尝试了老版的_thread进程库、尝试了主流的threading进程库、尝试了线程池的方法,终于找到一条适合我的方法。不容易呀

    判断功能的逻辑代码

    1. if choose == '判断':
    2. if len(panduans) == 0:
    3. tuichu = 0
    4. panduan = input('此功能的实现是基于颜色的RBG值来判断程序所要要执行的步骤块。\n现在,请选择你的‘先执行步骤块等待条件触发’或是‘直接等待条件触发’的操作:(输入"步骤块"或"等待")\n')
    5. if panduan == '如果':
    6. panduan_if = []
    7. while 1:
    8. click_dongzuo = input('请移动鼠标到目标位置上吸取颜色,输入“1”完成动作,输入“0”取消动作')
    9. if click_dongzuo == '1':
    10. xy = get_xy()
    11. click_color = GetColor(xy)
    12. panduan_yn = input(f'这个位置的RGB为:{click_color},是否确定为下一步骤块的判断根据?(输入"yes"or"no")\n')
    13. while 1:
    14. if panduan_yn == 'yes':
    15. get_caozuo_name()
    16. print(f'请选择满足当颜色为{click_color}时要执行的步骤包:')
    17. steps, steps_name = daoru()
    18. xunhuan_yn = input('这个步骤块是否循环执行至下一条件触发?(输入"yes"or"no")\n')
    19. while 1:
    20. if xunhuan_yn == 'yes':
    21. panduan_if.append('如果')
    22. panduan_if.append(xy)
    23. panduan_if.append(click_color)
    24. panduan_if.append(steps_name)
    25. panduan_if.append('循环')
    26. panduan_if.append(steps)
    27. panduans.append(panduan_if)
    28. print('添加成功,该步骤包将会循环')
    29. break
    30. elif xunhuan_yn == 'no':
    31. panduan_if.append('如果')
    32. panduan_if.append(xy)
    33. panduan_if.append(click_color)
    34. panduan_if.append(steps_name)
    35. panduan_if.append('不循环')
    36. panduan_if.append(steps)
    37. panduans.append(panduan_if)
    38. print('添加成功,该步骤包将只执行一次')
    39. break
    40. else:
    41. xunhuan_yn = input('你的输入有误,请输入"yes"or"no":')
    42. tuichu = 1
    43. break
    44. if panduan_yn == 'no':
    45. print('请重新选择')
    46. break
    47. else:
    48. panduan_yn = input('你的输入有误,请输入"yes"or"no"')
    49. if tuichu == 1:
    50. break
    51. elif click_dongzuo == '0':
    52. print('操作已取消')
    53. break
    54. else:
    55. print('请输入正确的操作(输入“0”或“1”)')
    56. if panduan == '步骤块':
    57. panduan_step = []
    58. steps, steps_name = daoru()
    59. xunhuan_yn = input('这个步骤块是否循环执行直至条件触发?(输入"yes"or"no")\n')
    60. while 1:
    61. if xunhuan_yn == 'yes':
    62. panduan_step.append('步骤块')
    63. panduan_step.append('循环')
    64. panduan_step.append(steps_name)
    65. panduan_step.append(steps)
    66. panduans.append(panduan_step)
    67. break
    68. elif xunhuan_yn == 'no':
    69. panduan_step.append('步骤块')
    70. panduan_step.append('不循环')
    71. panduan_step.append(steps_name)
    72. panduan_step.append(steps)
    73. panduans.append(panduan_step)
    74. break
    75. else:
    76. xunhuan_yn = input('你的输入有误,请输入"yes"or"no":')
    77. if panduan == '等待':
    78. panduan_if = []
    79. print('你选择了等待,程序将时刻检测目标位置的颜色以执行接下来的步骤块')
    80. panduan_if.append('等待')
    81. panduans.append(panduan_if)
    82. if panduan != '步骤块' and panduan != '如果' and panduan != '等待':
    83. print('你的输入有误')
    84. if len(panduans) > 0:
    85. print('你一录入了至少一个逻辑判断,请选择继续选择目标位置的颜色来触发接下来你选择的步骤块')
    86. panduan_if = []
    87. while 1:
    88. click_dongzuo = input('请移动鼠标到目标位置上吸取颜色,输入“1”完成动作,输入“0”取消动作')
    89. if click_dongzuo == '1':
    90. xy = get_xy()
    91. click_color = GetColor(xy)
    92. panduan_yn = input(f'这个位置的RGB为:{click_color},是否确定为下一步骤块的判断根据?(输入"yes"or"no")\n')
    93. while 1:
    94. if panduan_yn == 'yes':
    95. get_caozuo_name()
    96. print(f'请选择满足当颜色为{click_color}时要执行的步骤包:')
    97. steps, steps_name = daoru()
    98. xunhuan_yn = input('这个步骤块是否循环执行直至条件触发?(输入"yes"or"no")\n')
    99. while 1:
    100. if xunhuan_yn == 'yes':
    101. panduan_if.append('如果')
    102. panduan_if.append(xy)
    103. panduan_if.append(click_color)
    104. panduan_if.append(steps_name)
    105. panduan_if.append('循环')
    106. panduan_if.append(steps)
    107. panduans.append(panduan_if)
    108. print('添加成功,该步骤包将会循环')
    109. break
    110. elif xunhuan_yn == 'no':
    111. panduan_if.append('如果')
    112. panduan_if.append(xy)
    113. panduan_if.append(click_color)
    114. panduan_if.append(steps_name)
    115. panduan_if.append('不循环')
    116. panduan_if.append(steps)
    117. panduans.append(panduan_if)
    118. print('添加成功,该步骤包将只执行一次')
    119. break
    120. else:
    121. xunhuan_yn = input('你的输入有误,请输入"yes"or"no":')
    122. tuichu = 1
    123. break
    124. if panduan_yn == 'no':
    125. print('请重新选择')
    126. break
    127. else:
    128. panduan_yn = input('你的输入有误,请输入"yes"or"no"')
    129. if tuichu == 1:
    130. break
    131. elif click_dongzuo == '0':
    132. print('操作已取消')
    133. break
    134. else:
    135. print('请输入正确的操作(输入“0”或“1”)')

     逻辑执行功能的实现

    1. if choose == '逻辑执行':
    2. print('这里是逻辑执行库,所有的逻辑判断都会存储到这里')
    3. print(panduans)
    4. xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=('等待', '1', '循环'))
    5. xiancheng.setDaemon(True)
    6. xiancheng.start()
    7. for pan in panduans:
    8. state = '未触发'
    9. if pan[0] == '如果':
    10. print(pan[5])
    11. print(len(pan[5]))
    12. bu = str(pan[5])
    13. print(bu)
    14. bu = readListFromStr(bu)
    15. zhixing(bu)
    16. print(bu)
    17. if state == '未触发':
    18. if pan[4] == '循环':
    19. rgb = pan[2]
    20. rgb_xy = pan[1]
    21. _thread.start_new_thread(jianshi, ())
    22. while 1:
    23. if state == '触发':
    24. xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[3], pan[5], '循环'))
    25. xiancheng.start()
    26. state = '未触发'
    27. break
    28. if pan[4] == '不循环':
    29. rgb = pan[2]
    30. rgb_xy = pan[1]
    31. _thread.start_new_thread(jianshi, ())
    32. while 1:
    33. if state == '触发':
    34. xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[3], pan[5], '不循环'))
    35. xiancheng.start()
    36. state = '未触发'
    37. break
    38. if pan[0] == '步骤块':
    39. stop_thread(xiancheng)
    40. if pan[1] == '循环':
    41. xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[2], pan[3], '循环'))
    42. xiancheng.start()
    43. if pan[1] == '不循环':
    44. xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[2], pan[3], '不循环'))
    45. xiancheng.start()
    46. if pan[0] == '等待':
    47. print('程序正在监测目标位置RGB值')
    48. print('逻辑执行已全部执行完毕')
    49. break

    逻辑块存储功能的实现

    1. def listtotxt(list, path):
    2. import json
    3. c_list = list
    4. c_list = json.dumps(c_list)
    5. '''将c_list存入文件
    6. '''
    7. a = open(path, "w", encoding='UTF-8')
    8. a.write(c_list)
    9. a.close()
    10. print('已存入txt')

    逻辑块存储逻辑代码

    1. if choose == '逻辑块存储':
    2. yorn = input("确定保存?\n输入'yes'or'no'\n")
    3. while 1:
    4. if yorn == 'yes':
    5. if len(panduans) == 0:
    6. print('还未记录你任何操作,请添加操作再使用逻辑块存储功能')
    7. else:
    8. do_name = input('请为以上操作命名吧:')
    9. if '逻辑块存储' in do_name:
    10. do_name = input('抱歉,你的命名里不允许包含”逻辑块存储“,请重新命名')
    11. else:
    12. path = r"{}逻辑块存储.txt".format(do_name)
    13. listtotxt(list=panduans, path=path)
    14. break
    15. if yorn == 'no':
    16. print('你已取消存储')
    17. break
    18. else:
    19. yorn = input("请输入'yes'or'no':\n")

    逻辑块导入功能的实现

    1. def txttolist(path):
    2. import json
    3. b = open(path, "r", encoding='UTF-8')
    4. out = b.read()
    5. out = json.loads(out)
    6. return out

    逻辑块导入逻辑代码:

    1. if choose == '逻辑块导入':
    2. caozuojiyi = get_caozuokuai_name()
    3. while True:
    4. xunhuan_choose = input('已存储的操作有:{}\n请输入导入操作的操作名:'.format(caozuojiyi))
    5. if xunhuan_choose in caozuojiyi:
    6. break
    7. else:
    8. print('逻辑块存储库中并无你想要的操作,请重新输入:')
    9. caozuopath = r"{}逻辑块存储.txt".format(xunhuan_choose)
    10. panduans = txttolist(path=caozuopath)

    完整代码

    1. import threading
    2. import pyautogui
    3. from ctypes import *
    4. import time
    5. import os, sys
    6. import pyperclip
    7. import inspect
    8. import ctypes
    9. import _thread
    10. def _async_raise(tid, exctype):
    11. """raises the exception, performs cleanup if needed"""
    12. tid = ctypes.c_long(tid)
    13. if not inspect.isclass(exctype):
    14. exctype = type(exctype)
    15. res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
    16. if res == 0:
    17. raise ValueError("invalid thread id")
    18. elif res != 1:
    19. # """if it returns a number greater than one, you're in trouble,
    20. # and you should call it again with exc=NULL to revert the effect"""
    21. ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
    22. raise SystemError("PyThreadState_SetAsyncExc failed")
    23. def stop_thread(threa):
    24. _async_raise(threa.ident, SystemExit)
    25. def get_caozuo_name():
    26. dirname, filename = os.path.split(os.path.abspath(sys.argv[0]))
    27. files1 = []
    28. file_dir = r"{}".format(os.path.realpath(sys.argv[0])[:-13])
    29. for root, dirs, files in os.walk(file_dir, topdown=False):
    30. files = files[:-1]
    31. for i in files:
    32. if '.txt' in i:
    33. files1.append(i[:-4])
    34. return files1
    35. def get_caozuokuai_name():
    36. dirname, filename = os.path.split(os.path.abspath(sys.argv[0]))
    37. files1 = []
    38. file_dir = r"{}".format(os.path.realpath(sys.argv[0])[:-13])
    39. for root, dirs, files in os.walk(file_dir, topdown=False):
    40. files = files[:-1]
    41. for i in files:
    42. if '逻辑块存储.txt' in i:
    43. files1.append(i[:-9])
    44. return files1
    45. def writeList2txt(file, data):
    46. '''
    47. 将list写入txt
    48. :param data:
    49. :return:
    50. '''
    51. file.write(str(data), encoding='uft8')
    52. def readListFromStr(str):
    53. '''
    54. str -> List
    55. 除去冗余的方法调用
    56. :param str:
    57. :return:
    58. '''
    59. res, pos = help(str, 1)
    60. res1 = []
    61. a = '1'
    62. for ii in res:
    63. iii = []
    64. for i in ii:
    65. if type(i) == type(a):
    66. i = i.replace("'", "")
    67. iii.append(i)
    68. else:
    69. iii.append(i)
    70. res1.append(iii)
    71. return res1
    72. def help(str, startIndex):
    73. '''
    74. 单行字符串的读取,形成list
    75. :param str:
    76. :return:
    77. '''
    78. str = str.replace(" ", "") # 将所有空格删去
    79. res = []
    80. i = startIndex
    81. pre = startIndex
    82. while i < len(str):
    83. if str[i] == '[':
    84. # 将pre-i-2的字符都切片,切split
    85. if i - 2 >= pre:
    86. slice = str[pre:i - 1].split(',')
    87. for element in slice:
    88. res.append(element)
    89. # 递归调用 加入子list
    90. child, pos = help(str, i + 1)
    91. res.append(child)
    92. i = pos # i移动到pos位置,也就是递归的最后一个右括号
    93. pre = pos + 2 # 右括号之后是, [ 有三个字符,所以要+2至少
    94. elif str[i] == ']':
    95. # 将前面的全部放入列表
    96. if i - 1 >= pre:
    97. slice = str[pre:i].split(',')
    98. for element in slice:
    99. res.append(element)
    100. return res, i
    101. i = i + 1
    102. return res, i
    103. def get_caozuo(caozuopath):
    104. with open(caozuopath, 'r', encoding='utf8') as f:
    105. data = f.read()
    106. return data
    107. def get_xy():
    108. x, y = pyautogui.position()
    109. return [x, y]
    110. def GetColor(xy):
    111. x = xy[0]
    112. y = xy[1]
    113. r = 0
    114. g = 0
    115. b = 0
    116. try:
    117. gdi32 = windll.gdi32
    118. user32 = windll.user32
    119. hdc = user32.GetDC(None) # 获取颜色值
    120. pixel = gdi32.GetPixel(hdc, x, y) # 提取RGB值
    121. r = pixel & 0x0000ff
    122. g = (pixel & 0x00ff00) >> 8
    123. b = pixel >> 16
    124. except KeyboardInterrupt:
    125. print('\n')
    126. return [r, g, b]
    127. def timer(timex):
    128. time.sleep(timex)
    129. def clicker_cishu(cishu, x, y, pinlv):
    130. for a in range(cishu):
    131. pyautogui.click(x, y)
    132. time.sleep(pinlv)
    133. def clicker_time(shijian, x, y, pinlv):
    134. start = time.time()
    135. while True:
    136. pyautogui.click(x, y)
    137. time.sleep(pinlv)
    138. end = time.time()
    139. shijian1 = end - start
    140. if shijian1 >= shijian:
    141. break
    142. def zhixing(step):
    143. for i in step:
    144. if i[0] == '点击':
    145. x = int(i[1][0])
    146. y = int(i[1][1])
    147. pyautogui.click(x, y)
    148. print(f'已执行完点击动作,点击坐标位置:X:{x},Y:{y} ')
    149. if i[0] == '延时':
    150. t = int(i[1])
    151. timer(t)
    152. print(f'已执行完延时动作,延时时长:{t}秒')
    153. if i[0] == '连点':
    154. if i[2] == '连点次数':
    155. clicker_cishu(int(i[3]), int(i[1][0]), int(i[1][1]), int(i[4]))
    156. print(f'已执行完连点操作,你选择的是{i[2]},连点次数是{i[4]}')
    157. if i[2] == '连点时长':
    158. clicker_time(int(i[3]), int(i[1][0]), int(i[1][1]), int(i[4]))
    159. print(f'已执行完连点操作,你选择的是{i[2]},连点时长是{i[4]}秒')
    160. if i[0] == '拖拽':
    161. pyautogui.moveTo(int(i[1][0]), int(i[1][1]))
    162. pyautogui.dragTo(int(i[2][0]), int(i[2][1]), 1, button='left')
    163. print(f'已执行拖拽动作,拖拽起始位置是X:{int(i[1][0])},Y:{int(i[1][1])},拖拽后的位置是X:{int(i[2][0])},Y:{int(i[2][1])}')
    164. if i[0] == '双击':
    165. pyautogui.click(int(i[1][0]), int(i[1][1]))
    166. pyautogui.click(int(i[1][0]), int(i[1][1]))
    167. print(f'已执行完点击动作,点击坐标位置:X:{int(i[1][0])},Y:{int(i[1][1])} ')
    168. if i[0] == '输入':
    169. pyautogui.click(int(i[1][0]), int(i[1][1]))
    170. pyperclip.copy(i[2])
    171. time.sleep(0.1)
    172. pyautogui.hotkey('ctrl', 'v')
    173. if i[0] == '按键':
    174. pyautogui.hotkey(*i[1])
    175. if i[0] == '右击':
    176. x = int(i[1][0])
    177. y = int(i[1][1])
    178. pyautogui.rightClick(x, y)
    179. print(f'已执行完右击动作,点击坐标位置:X:{x},Y:{y} ')
    180. if i[0] == '中击':
    181. x = int(i[1][0])
    182. y = int(i[1][1])
    183. pyautogui.middleClick(x, y)
    184. print(f'已执行完中击动作,点击坐标位置:X:{x},Y:{y} ')
    185. if i[0] == '滚动':
    186. import pywinauto.mouse
    187. x, y = pyautogui.position()
    188. pywinauto.mouse.scroll((x, y), i[1]) # (1100,300)是初始坐标,1000是滑动距离(可负)
    189. def cunchu():
    190. yorn = input("执行完毕,是否保存?\n输入'yes'or'no'\n")
    191. while 1:
    192. if yorn == 'yes':
    193. if len(step) == 0:
    194. print('还未记录你任何操作,请添加操作再使用存储功能')
    195. else:
    196. do_name = input('请为以上操作命名吧:')
    197. path = r"{}.txt".format(do_name)
    198. listtotxt(list=step, path=path)
    199. break
    200. if yorn == 'no':
    201. print('你已取消存储')
    202. break
    203. else:
    204. yorn = input("请输入'yes'or'no':\n")
    205. def chakan():
    206. if len(step) == 0:
    207. print('暂未录入操作,请先录入操作再查看')
    208. zizeng = 1
    209. for i in step:
    210. if i[0] == '点击':
    211. x = int(i[1][0])
    212. y = int(i[1][1])
    213. print(f'第{zizeng}步:\n执行点击动作,点击坐标位置:X:{x},Y:{y} ')
    214. if i[0] == '延时':
    215. t = int(i[1])
    216. print(f'第{zizeng}步:\n执行延时动作,延时时长:{t}秒')
    217. if i[0] == '连点':
    218. if i[2] == '连点次数':
    219. print(f'第{zizeng}步:\n执行连点操作,你选择的是{i[2]},连点次数是{i[4]}')
    220. if i[2] == '连点时长':
    221. print(f'第{zizeng}步:\n执行连点操作,你选择的是{i[2]},连点时长是{i[4]}秒')
    222. if i[0] == '拖拽':
    223. print(
    224. f'第{zizeng}步:\n执行拖拽动作,拖拽起始位置是X:{int(i[1][0])},Y:{int(i[1][1])},拖拽后的位置是X:{int(i[2][0])},Y:{int(i[2][1])}')
    225. if i[0] == '双击':
    226. print(f'第{zizeng}步:\n执行点击动作,点击坐标位置:X:{int(i[1][0])},Y:{int(i[1][1])} ')
    227. if i[0] == '按键':
    228. print(f'第{zizeng}步:\n执行按键动作,将同时按下”{i[1]}“键')
    229. zizeng += 1
    230. def daoru():
    231. caozuojiyi = get_caozuo_name()
    232. while True:
    233. xunhuan_choose = input('已存储的操作有:{}\n请输入导入操作的操作名:'.format(caozuojiyi))
    234. if xunhuan_choose in caozuojiyi:
    235. break
    236. else:
    237. print('存储库中并无你想要的操作,请重新输入:')
    238. caozuopath = r'{}.txt'.format(xunhuan_choose)
    239. step1 = txttolist(caozuopath)
    240. print(step1)
    241. return [step1, xunhuan_choose]
    242. def jianshi():
    243. global state, rgb, rgb_xy, xiancheng
    244. while 1:
    245. aa = GetColor(rgb_xy)
    246. if aa == rgb:
    247. try:
    248. stop_thread(xiancheng)
    249. finally:
    250. state = '触发'
    251. print(f'检测到{rgb_xy}位置的RGB值变为{aa}')
    252. break
    253. def zhixingbuzhoukuai(buzhou, bu, xunhuanyn):
    254. global state
    255. print(f'正在执行"{buzhou}"代码块的操作')
    256. state = '未触发'
    257. if bu == '1':
    258. while 1:
    259. if state == '触发':
    260. break
    261. if state == '未触发':
    262. timer(0.1)
    263. elif xunhuanyn == '循环':
    264. while 1:
    265. if state == '触发':
    266. break
    267. if state == '未触发':
    268. zhixing(bu)
    269. elif xunhuanyn == '不循环':
    270. zhixing(bu)
    271. def listtotxt(list, path):
    272. import json
    273. c_list = list
    274. c_list = json.dumps(c_list)
    275. '''将c_list存入文件
    276. '''
    277. a = open(path, "w", encoding='UTF-8')
    278. a.write(c_list)
    279. a.close()
    280. print('已存入txt')
    281. def txttolist(path):
    282. import json
    283. b = open(path, "r", encoding='UTF-8')
    284. out = b.read()
    285. out = json.loads(out)
    286. return out
    287. rgb_xy = []
    288. rgb = []
    289. state = '未触发'
    290. panduans = []
    291. step = []
    292. while True:
    293. choose = input('请输入你需要使用的功能:')
    294. if choose == '点击':
    295. click = []
    296. while 1:
    297. click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
    298. if click_dongzuo == '1':
    299. click_weizhi = get_xy()
    300. click.append('点击')
    301. click.append(click_weizhi)
    302. step.append(click)
    303. break
    304. elif click_dongzuo == '0':
    305. print('操作已取消')
    306. break
    307. else:
    308. print('请输入正确的操作(输入“0”或“1”')
    309. if choose == '延时':
    310. while 1:
    311. timerr = []
    312. try:
    313. timex = int(input('请输入延时时间:'))
    314. timerr.append('延时')
    315. timerr.append(timex)
    316. step.append(timerr)
    317. break
    318. except:
    319. print('延时失败/n请输入正确的延时时间')
    320. continue
    321. if choose == '连点':
    322. click_liandian = []
    323. while 1:
    324. click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
    325. if click_dongzuo == '1':
    326. click_weizhi = get_xy()
    327. click_liandian.append('连点')
    328. click_liandian.append(click_weizhi)
    329. break
    330. elif click_dongzuo == '0':
    331. print('操作已取消')
    332. break
    333. else:
    334. print('请输入正确的操作(输入“0”或“1”')
    335. click_pinlv = float(input('请输入连点频率:'))
    336. while 1:
    337. click_stop_choose = input('“连点次数”or“连点时长”')
    338. if click_stop_choose == '连点次数':
    339. click_cishu = int(input('请输入连点次数:'))
    340. click_liandian.append('连点次数')
    341. click_liandian.append(click_cishu)
    342. click_liandian.append(click_pinlv)
    343. step.append(click_liandian)
    344. print(click_liandian)
    345. print(step)
    346. break
    347. if click_stop_choose == '连点时长':
    348. click_shichang = int(input('请输入连点时长(秒):'))
    349. click_liandian.append('连点时长')
    350. click_liandian.append(click_shichang)
    351. step.append(click_liandian)
    352. click_liandian.append(click_pinlv)
    353. print(click_liandian)
    354. print(step)
    355. break
    356. else:
    357. continue
    358. if choose == '存储':
    359. if len(step) == 0:
    360. print('还未记录你任何操作,请添加操作再使用存储功能')
    361. else:
    362. do_name = input('请为以上操作命名吧:')
    363. path = r"{}.txt".format(do_name)
    364. listtotxt(list=step, path=path)
    365. if choose == '拖拽':
    366. tuozhuai = []
    367. while 1:
    368. click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成移动前的位置输入,输入“0”取消动作')
    369. if click_dongzuo == '1':
    370. click_weizhi = get_xy()
    371. tuozhuai.append('拖拽')
    372. tuozhuai.append(click_weizhi)
    373. while 1:
    374. click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成移动后的位置输入,输入“0”取消动作')
    375. if click_dongzuo == '1':
    376. click_weizhi = get_xy()
    377. tuozhuai.append(click_weizhi)
    378. break
    379. elif click_dongzuo == '0':
    380. print('操作已取消')
    381. break
    382. else:
    383. print('请输入正确的操作(输入“0”或“1”')
    384. break
    385. elif click_dongzuo == '0':
    386. print('操作已取消')
    387. break
    388. else:
    389. print('请输入正确的操作(输入“0”或“1”')
    390. step.append(tuozhuai)
    391. if choose == '循环执行':
    392. while 1:
    393. xunhuan_cishu_zhixing = 0
    394. xunhuan_cishu = input('请输入循环次数(如要无限循环请输入"无限"):')
    395. if xunhuan_cishu == '无限':
    396. while True:
    397. zhixing(step)
    398. if xunhuan_cishu.isdigit():
    399. for i in range(int(xunhuan_cishu)):
    400. xunhuan_cishu_zhixing += 1
    401. zhixing(step)
    402. print(f'已完成{xunhuan_cishu_zhixing}次循环')
    403. break
    404. else:
    405. print('你的输入有误,请重新输入:')
    406. if choose == '导入':
    407. if len(step) == 0:
    408. step = daoru()[0]
    409. else:
    410. baocun_choose = input('此次操作若未保存请先,导入别的操作会覆盖原来的操作,你确定要导入吗?\n请输入“yes”or“no”:\n')
    411. while 1:
    412. if baocun_choose == 'no':
    413. break
    414. if baocun_choose == 'yes':
    415. print('你已取消保存')
    416. step = daoru()[0]
    417. break
    418. else:
    419. yorn = input("请输入'yes'or'no':\n")
    420. if choose == '输入':
    421. shuru = []
    422. while 1:
    423. click_dongzuo = input('请移动鼠标到你要输入的位置上输入“1”完成动作,输入“0”取消动作')
    424. if click_dongzuo == '1':
    425. click_weizhi = get_xy()
    426. txt_in = input('请输入你要在该位置输入的文字:\n')
    427. shuru.append('输入')
    428. shuru.append(click_weizhi)
    429. shuru.append(txt_in)
    430. step.append(shuru)
    431. break
    432. elif click_dongzuo == '0':
    433. print('操作已取消')
    434. break
    435. else:
    436. print('请输入正确的操作(输入“0”或“1”')
    437. if choose == '按键':
    438. while 1:
    439. anjian = input('这是模拟操作键盘的操作(例如复制,输入’ctrl‘ + ’c‘):\n')
    440. if anjian != 'q':
    441. anjian = anjian.split('+')
    442. anjians = []
    443. a = []
    444. for an in anjian:
    445. an = an.replace("‘", "").replace("’", "").strip()
    446. if an in pyautogui.KEYBOARD_KEYS:
    447. anjians.append(an)
    448. nihaofan = 0
    449. else:
    450. print('你的输入不合法')
    451. nihaofan = 1
    452. break
    453. if nihaofan == 0:
    454. a.append('按键')
    455. a.append(anjians)
    456. step.append(a)
    457. print('录入成功')
    458. break
    459. if anjian == 'q':
    460. break
    461. if choose == '双击':
    462. click_double = []
    463. while 1:
    464. click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
    465. if click_dongzuo == '1':
    466. click_weizhi = get_xy()
    467. click_double.append('双击')
    468. click_double.append(click_weizhi)
    469. step.append(click_double)
    470. break
    471. elif click_dongzuo == '0':
    472. print('操作已取消')
    473. break
    474. else:
    475. print('请输入正确的操作(输入“0”或“1”')
    476. if choose == '滚动':
    477. while 1:
    478. gundong = []
    479. try:
    480. gundong1 = int(input('这里是模拟鼠标滚动,请输入你要滚动距离(正数为向上移动,负数为向下移动):\n'))
    481. gundong.append('滚动')
    482. gundong.append(gundong1)
    483. step.append(gundong)
    484. break
    485. except:
    486. print('你的输入有误,请重新输入')
    487. if choose == '查看':
    488. chakan()
    489. if choose == '右击':
    490. click_r = []
    491. while 1:
    492. click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
    493. if click_dongzuo == '1':
    494. click_weizhi = get_xy()
    495. click_r.append('右击')
    496. click_r.append(click_weizhi)
    497. step.append(click_r)
    498. break
    499. elif click_dongzuo == '0':
    500. print('操作已取消')
    501. break
    502. else:
    503. print('请输入正确的操作(输入“0”或“1”')
    504. if choose == '中击':
    505. click_m = []
    506. while 1:
    507. click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
    508. if click_dongzuo == '1':
    509. click_weizhi = get_xy()
    510. click_m.append('中击')
    511. click_m.append(click_weizhi)
    512. step.append(click_m)
    513. break
    514. elif click_dongzuo == '0':
    515. print('操作已取消')
    516. break
    517. else:
    518. print('请输入正确的操作(输入“0”或“1”')
    519. if choose == '执行':
    520. if len(step) == 0:
    521. print('你还未记录任何操作,请至少记录了一个操作再执行')
    522. else:
    523. zhixing(step)
    524. cunchu()
    525. if choose == '判断':
    526. if len(panduans) == 0:
    527. tuichu = 0
    528. panduan = input('此功能的实现是基于颜色的RBG值来判断程序所要要执行的步骤块。\n现在,请选择你的‘先执行步骤块等待条件触发’或是‘直接等待条件触发’的操作:(输入"步骤块"或"等待")\n')
    529. if panduan == '如果':
    530. panduan_if = []
    531. while 1:
    532. click_dongzuo = input('请移动鼠标到目标位置上吸取颜色,输入“1”完成动作,输入“0”取消动作')
    533. if click_dongzuo == '1':
    534. xy = get_xy()
    535. click_color = GetColor(xy)
    536. panduan_yn = input(f'这个位置的RGB为:{click_color},是否确定为下一步骤块的判断根据?(输入"yes"or"no")\n')
    537. while 1:
    538. if panduan_yn == 'yes':
    539. get_caozuo_name()
    540. print(f'请选择满足当颜色为{click_color}时要执行的步骤包:')
    541. steps, steps_name = daoru()
    542. xunhuan_yn = input('这个步骤块是否循环执行至下一条件触发?(输入"yes"or"no")\n')
    543. while 1:
    544. if xunhuan_yn == 'yes':
    545. panduan_if.append('如果')
    546. panduan_if.append(xy)
    547. panduan_if.append(click_color)
    548. panduan_if.append(steps_name)
    549. panduan_if.append('循环')
    550. panduan_if.append(steps)
    551. panduans.append(panduan_if)
    552. print('添加成功,该步骤包将会循环')
    553. break
    554. elif xunhuan_yn == 'no':
    555. panduan_if.append('如果')
    556. panduan_if.append(xy)
    557. panduan_if.append(click_color)
    558. panduan_if.append(steps_name)
    559. panduan_if.append('不循环')
    560. panduan_if.append(steps)
    561. panduans.append(panduan_if)
    562. print('添加成功,该步骤包将只执行一次')
    563. break
    564. else:
    565. xunhuan_yn = input('你的输入有误,请输入"yes"or"no":')
    566. tuichu = 1
    567. break
    568. if panduan_yn == 'no':
    569. print('请重新选择')
    570. break
    571. else:
    572. panduan_yn = input('你的输入有误,请输入"yes"or"no"')
    573. if tuichu == 1:
    574. break
    575. elif click_dongzuo == '0':
    576. print('操作已取消')
    577. break
    578. else:
    579. print('请输入正确的操作(输入“0”或“1”)')
    580. if panduan == '步骤块':
    581. panduan_step = []
    582. steps, steps_name = daoru()
    583. xunhuan_yn = input('这个步骤块是否循环执行直至条件触发?(输入"yes"or"no")\n')
    584. while 1:
    585. if xunhuan_yn == 'yes':
    586. panduan_step.append('步骤块')
    587. panduan_step.append('循环')
    588. panduan_step.append(steps_name)
    589. panduan_step.append(steps)
    590. panduans.append(panduan_step)
    591. break
    592. elif xunhuan_yn == 'no':
    593. panduan_step.append('步骤块')
    594. panduan_step.append('不循环')
    595. panduan_step.append(steps_name)
    596. panduan_step.append(steps)
    597. panduans.append(panduan_step)
    598. break
    599. else:
    600. xunhuan_yn = input('你的输入有误,请输入"yes"or"no":')
    601. if panduan == '等待':
    602. panduan_if = []
    603. print('你选择了等待,程序将时刻检测目标位置的颜色以执行接下来的步骤块')
    604. panduan_if.append('等待')
    605. panduans.append(panduan_if)
    606. if panduan != '步骤块' and panduan != '如果' and panduan != '等待':
    607. print('你的输入有误')
    608. if len(panduans) > 0:
    609. print('你一录入了至少一个逻辑判断,请选择继续选择目标位置的颜色来触发接下来你选择的步骤块')
    610. panduan_if = []
    611. while 1:
    612. click_dongzuo = input('请移动鼠标到目标位置上吸取颜色,输入“1”完成动作,输入“0”取消动作')
    613. if click_dongzuo == '1':
    614. xy = get_xy()
    615. click_color = GetColor(xy)
    616. panduan_yn = input(f'这个位置的RGB为:{click_color},是否确定为下一步骤块的判断根据?(输入"yes"or"no")\n')
    617. while 1:
    618. if panduan_yn == 'yes':
    619. get_caozuo_name()
    620. print(f'请选择满足当颜色为{click_color}时要执行的步骤包:')
    621. steps, steps_name = daoru()
    622. xunhuan_yn = input('这个步骤块是否循环执行直至条件触发?(输入"yes"or"no")\n')
    623. while 1:
    624. if xunhuan_yn == 'yes':
    625. panduan_if.append('如果')
    626. panduan_if.append(xy)
    627. panduan_if.append(click_color)
    628. panduan_if.append(steps_name)
    629. panduan_if.append('循环')
    630. panduan_if.append(steps)
    631. panduans.append(panduan_if)
    632. print('添加成功,该步骤包将会循环')
    633. break
    634. elif xunhuan_yn == 'no':
    635. panduan_if.append('如果')
    636. panduan_if.append(xy)
    637. panduan_if.append(click_color)
    638. panduan_if.append(steps_name)
    639. panduan_if.append('不循环')
    640. panduan_if.append(steps)
    641. panduans.append(panduan_if)
    642. print('添加成功,该步骤包将只执行一次')
    643. break
    644. else:
    645. xunhuan_yn = input('你的输入有误,请输入"yes"or"no":')
    646. tuichu = 1
    647. break
    648. if panduan_yn == 'no':
    649. print('请重新选择')
    650. break
    651. else:
    652. panduan_yn = input('你的输入有误,请输入"yes"or"no"')
    653. if tuichu == 1:
    654. break
    655. elif click_dongzuo == '0':
    656. print('操作已取消')
    657. break
    658. else:
    659. print('请输入正确的操作(输入“0”或“1”)')
    660. if choose == '逻辑执行':
    661. print('这里是逻辑执行库,所有的逻辑判断都会存储到这里')
    662. print(panduans)
    663. xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=('等待', '1', '循环'))
    664. xiancheng.setDaemon(True)
    665. xiancheng.start()
    666. for pan in panduans:
    667. state = '未触发'
    668. if pan[0] == '如果':
    669. print(pan[5])
    670. print(len(pan[5]))
    671. bu = str(pan[5])
    672. print(bu)
    673. bu = readListFromStr(bu)
    674. zhixing(bu)
    675. print(bu)
    676. if state == '未触发':
    677. if pan[4] == '循环':
    678. rgb = pan[2]
    679. rgb_xy = pan[1]
    680. _thread.start_new_thread(jianshi, ())
    681. while 1:
    682. if state == '触发':
    683. xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[3], pan[5], '循环'))
    684. xiancheng.start()
    685. state = '未触发'
    686. break
    687. if pan[4] == '不循环':
    688. rgb = pan[2]
    689. rgb_xy = pan[1]
    690. _thread.start_new_thread(jianshi, ())
    691. while 1:
    692. if state == '触发':
    693. xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[3], pan[5], '不循环'))
    694. xiancheng.start()
    695. state = '未触发'
    696. break
    697. if pan[0] == '步骤块':
    698. stop_thread(xiancheng)
    699. if pan[1] == '循环':
    700. xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[2], pan[3], '循环'))
    701. xiancheng.start()
    702. if pan[1] == '不循环':
    703. xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[2], pan[3], '不循环'))
    704. xiancheng.start()
    705. if pan[0] == '等待':
    706. print('程序正在监测目标位置RGB值')
    707. print('逻辑执行已全部执行完毕')
    708. break
    709. if choose == '逻辑块存储':
    710. yorn = input("确定保存?\n输入'yes'or'no'\n")
    711. while 1:
    712. if yorn == 'yes':
    713. if len(panduans) == 0:
    714. print('还未记录你任何操作,请添加操作再使用逻辑块存储功能')
    715. else:
    716. do_name = input('请为以上操作命名吧:')
    717. if '逻辑块存储' in do_name:
    718. do_name = input('抱歉,你的命名里不允许包含”逻辑块存储“,请重新命名')
    719. else:
    720. path = r"{}逻辑块存储.txt".format(do_name)
    721. listtotxt(list=panduans, path=path)
    722. break
    723. if yorn == 'no':
    724. print('你已取消存储')
    725. break
    726. else:
    727. yorn = input("请输入'yes'or'no':\n")
    728. if choose == '逻辑块导入':
    729. caozuojiyi = get_caozuokuai_name()
    730. while True:
    731. xunhuan_choose = input('已存储的操作有:{}\n请输入导入操作的操作名:'.format(caozuojiyi))
    732. if xunhuan_choose in caozuojiyi:
    733. break
    734. else:
    735. print('逻辑块存储库中并无你想要的操作,请重新输入:')
    736. caozuopath = r"{}逻辑块存储.txt".format(xunhuan_choose)
    737. panduans = txttolist(path=caozuopath)
    738. if choose == 'q' or choose == 'quit' or choose == '退出' or choose == 'close':
    739. break
    740. if choose == 'tips' or choose == '提示' or choose == 'help' or choose == '帮助':
    741. print(
    742. '''你可以输入'点击', '右击', '中击', '逻辑执行', '判断', '滚动', '延时', '存储', '执行', '循环执行', '拖拽', '连点', '输入', '双击', '查看',
    743. '导入', 'q', 'quit','退出', 'close', 'tips', '提示', 'help', '帮助', '按键'来帮助你完成你的自动化操作''')
    744. if not choose in ['点击', '右击', '中击', '逻辑执行', '判断', '滚动', '延时', '存储', '执行', '循环执行', '拖拽', '连点', '输入', '双击', '查看',
    745. '导入', 'q', 'quit','退出', 'close', 'tips', '提示', 'help', '帮助', '按键']:
    746. print('你的输入有误或暂未开发此功能,请重新输入(输入”help“获得提示)')
    747. print('代码已全部执行完毕,程序已退出')

    这是我的2.0版本,之前把逻辑板块之外的功能都写出来了之后迫不及待地玩了一下,帮朋友买了四价,做了微信信息轰炸的程序,看着鼠标把文件夹拖来拖去,做了些拳皇脚本打出超级连招,等会我再试一下盲僧的马氏三角杀哈哈哈,想想就兴奋~~

    本来还想做多点功能的,比如:检测目标区域的文字来执行判断操作(这听起来不难);

    写个语音输入功能,当执行完什么操作了就让电脑说:“你好厉害啊”、“真的是我的偶像”、“快来看看我抢到四价了”(现在我就能写出来);

    1. import pyttsx3
    2. engine = pyttsx3.init()
    3. engine.say('我抢到了!快来看一下')
    4. engine.runAndWait()

    当然暂时还没有这些需求,如果我哪天有空就再更新到3.0版本哈,你们感兴趣的可以自己添加功能,至少我语音功能的逻辑代码已经给你们了。真不是懒【偷笑】

    艾玛,居然发了三万多字了,不聊了不聊了。

    不过都发这么多了,最后还是麻烦关注、点赞、收藏下哈。我喜欢在我的博客上分享一些有趣的代码,我跟别人不一样,我不卖课~~纯分享~~喜欢回复私信和留言~~~~     

    不定期更新~~~~

  • 相关阅读:
    杰理之AT 包格式【篇】
    用户身份标识与账号体系实践
    【Linux】进程间通信
    浅谈BIM技术在“智慧工地”建设中的应用
    go 线程限制数量v1 --chatGPT
    第7章 访问控制技术原理与应用
    Linux网络编程:网络协议及网络传输的基本流程
    【云原生】手把手教你搭建ferry开源工单系统
    ICML2021 | RSD: 一种基于几何距离的可迁移回归表征学习方法
    SpringBoot的基本使用
  • 原文地址:https://blog.csdn.net/m0_62814033/article/details/126231082