怎麼利用Python實作自訂連點器

王林
發布: 2023-05-12 20:43:04
轉載
2773 人瀏覽過

    前言

    前幾天留意到我媽一直在預約四價疫苗都約不上,就想著寫個程式來模擬人的操作去點擊,判斷疫苗是否被搶完,無限循環去刷新這個頁面,一旦疫苗可預約就立刻搶下來選擇時間接種人。當預約成功後就語音循環播報:已經搶到,趕緊過來看。

    基於上述的想法和需求,我花了半小時編輯了以下程式碼,並在一小時內成功預約。

    import pyautogui
    from ctypes import *  # 获取屏幕上某个坐标的颜色
    from time import sleep
    import time
     
    start = time.time()
    def get_color(x, y):
        gdi32 = windll.gdi32
        user32 = windll.user32
        hdc = user32.GetDC(None)  # 获取颜色值
        pixel = gdi32.GetPixel(hdc, x, y)  # 提取RGB值
        r = pixel & 0x0000ff
        g = (pixel & 0x00ff00) >> 8
        b = pixel >> 16
        return [r, g, b]
    print(get_color(297,454))
    while True:
        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]:
            pyautogui.click(310,255)#点进去抢
            sleep(0.5)
            pyautogui.click(467,262)#选择预约时间
            while True:
                if get_color(297,454) == [0,142,255]:
                    break
                else:
                    sleep(0.3)
            sleep(0.5)
            pyautogui.click(498,454)#点击下午
            sleep(0.5)
            pyautogui.click(467,520)#选择时间
            sleep(0.5)
            pyautogui.click(470,899)#点选好了
            sleep(0.5)
            pyautogui.click(470, 899)#点立即预约
            #sleep()
            break
        else:
            pyautogui.click(123,60)
            sleep(0.8)#刷新
    print('总耗时:'.format(time.time()-start))
    print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
    while 1:
        import pyttsx3
        engine = pyttsx3.init()
        engine.say('我抢到了!快来看一下')
        engine.runAndWait()
        sleep(1)
    登入後複製

    實作思維大致流程圖:

    怎麼利用Python實作自訂連點器

    可以看到邏輯非常簡單即可實現我想要的功能,不過即使是這樣,我也花了差不多半小時的時間來寫程式。於是我就在想,如果以後我要開發搶票、技能連招啊、信息轟炸朋友啊等等的功能,是不是也要這麼多時間呢,那我能不能自己造輪子來快速幫我開發我想要的腳本呢。

    整體思路

    一般需要的功能有:點選、延遲、連點、拖曳。一般這四個功能就能完成絕大多數的簡單的輔助腳本開發了,但我想做得稍微高級一點,功能多一點,就想另外開發:循環、判斷、模擬按鍵、文本輸入、存儲操作、讀取操作的功能。

    那麼我們就要朝著我們想要實現的九大功能來開發:循環、點擊、延時、連點、拖曳、判斷、模擬按鍵、文字輸入、儲存操作、讀取操作。

    首先就是希望我的每一步操作都會被程式記錄下來並執行,我們可以定義一個清單來儲存每一個動作,清單中的每一個元素就是每一步的操作,然後遍歷這個清單來讀取並執行每一個操作就可以將一整個操作全部執行。

    當我的每一步操作都輸入完畢後,我都希望程式能自動幫我把程式儲存下來方便我下次使用,這樣下次使用就不用再編譯多一次了。

    每個清單的第0項就是需要操作的功能,第0項之後都是各種參數。

    所有功能

    簡單示範

    怎麼利用Python實作自訂連點器

    點擊功能

    要想電腦幫我們點擊,首先要告訴電腦我要點擊的位置在哪裡。想要取得滑鼠位置就需要用到pyautogui函式庫,而這個函式庫下方有個position()方法可以傳回滑鼠位置的X座標,Y座標。

    定義獲取位置函數

    import pyautogui
    def get_xy():
        x, y = pyautogui.position()
        return [x,y]
    登入後複製

    用物件導向思想來簡化程序,提高程式碼復用率,使程式可讀性更高,是python開發的重要思想之一哦

    pyautogui庫還有非常多常見功能,有興趣的可以翻閱我之前寫的博客:Python速成篇之像selenium一樣操作電腦詳解

    點擊功能代碼如下

    step=[]
    while True:
        choose = input('请输入你需要使用的功能:')
        if choose == '点击':
            click = []
            while 1:
                click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
                if click_dongzuo == '1':
                    click_weizhi = get_xy()
                    click.append('点击')
                    click.append(click_weizhi)
                    step.append(click)
                    break
                elif click_dongzuo == '0':
                    print('操作已取消')
                    break
                else:
                    print('请输入正确的操作(输入“0”或“1”')
    登入後複製

    執行時的邏輯

                for i in step1:
                    if i[0] == '点击':
                        x = int(i[1][0])
                        y = int(i[1][1])
                        print(f'{x},{y}')
                        pyautogui.click(x,y)
    登入後複製

    記錄點擊需要記錄點擊功能、位置參數產生一個列表,然後將列表append到step總列表中去

    延時功能

    使用到了python內建庫中的time模組,可以使程式強制停止對應時間。將參數產生列表append到step總列表中去

    if choose =='延时':
        while 1:
            timerr = []
            try:
                timex = int(input('请输入延时时间:'))
                timerr.append('延时')
                timerr.append(timex)
                step.append(timerr)
                break
            except:
                print('延时失败/n请输入正确的延时时间')
                continue
    登入後複製

    執行時的邏輯 

    def timer(timex):
        time.sleep(timex)
    if i[0] == '延时':
        t = int(i[1])
        timer(t)
    登入後複製

    連點功能

    有些簡單的頁面可以透過連點來實現搶票等功能,這個功能必不可少

    記錄這個動作的必要參數有連點功能記錄、點擊頻率參數、透過連點次數完成動作還是透過連點時長完成動作。

    同樣是呼叫了獲取滑鼠位置的函數,

    if choose == '连点':
        click_liandian = []
        while 1:
            click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
            if click_dongzuo == '1':
                click_weizhi = get_xy()
                click_liandian.append('连点')
                click_liandian.append(click_weizhi)
                break
            elif click_dongzuo == '0':
                print('操作已取消')
                break
            else:
                print('请输入正确的操作(输入“0”或“1”')
        click_pinlv = float(input('请输入连点频率:'))
        while 1:
            click_stop_choose = input('“连点次数”or“连点时长”')
            if click_stop_choose =='连点次数':
                click_cishu = int(input('请输入连点次数:'))
                click_liandian.append('连点次数')
                click_liandian.append(click_cishu)
                click_liandian.append(click_pinlv)
                step.append(click_liandian)
                print(click_liandian)
                print(step)
                break
            if click_stop_choose == '连点时长':
                click_shichang = int(input('请输入连点时长(秒):'))
                click_liandian.append('连点时长')
                click_liandian.append(click_shichang)
                step.append(click_liandian)
                click_liandian.append(click_pinlv)
                print(click_liandian)
                print(step)
                break
            else:
                continue
    登入後複製

    執行時的邏輯

        if choose == '连点':
            click_liandian = []
            while 1:
                click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
                if click_dongzuo == '1':
                    click_weizhi = get_xy()
                    click_liandian.append('连点')
                    click_liandian.append(click_weizhi)
                    break
                elif click_dongzuo == '0':
                    print('操作已取消')
                    break
                else:
                    print('请输入正确的操作(输入“0”或“1”')
            click_pinlv = float(input('请输入连点频率:'))
            while 1:
                click_stop_choose = input('“连点次数”or“连点时长”')
                if click_stop_choose =='连点次数':
                    click_cishu = int(input('请输入连点次数:'))
                    click_liandian.append('连点次数')
                    click_liandian.append(click_cishu)
                    click_liandian.append(click_pinlv)
                    step.append(click_liandian)
                    print(click_liandian)
                    print(step)
                    break
                if click_stop_choose == '连点时长':
                    click_shichang = int(input('请输入连点时长(秒):'))
                    click_liandian.append('连点时长')
                    click_liandian.append(click_shichang)
                    step.append(click_liandian)
                    click_liandian.append(click_pinlv)
                    print(click_liandian)
                    print(step)
                    break
                else:
                    continue
    登入後複製

    儲存功能

    當我們記錄完所有操作後我們希望將操作保存下來方便下次使用,不需要從頭輸入。

    這將產生一個與py腳本同級的txt文件,txt檔案中保存了所有的步驟,可直接讀取使用

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

    讀取功能

    這一步呢就稍微麻煩一點,因為txt沒辦法記錄list類型的數據,只能以str類型寫出去並且只能以str類型讀取進來。我自己定義了一些函數來轉換成list類型,比較複雜,就不再說明函數是怎麼實現的,日後有機會再跟各位分享。

    def writeList2txt(file,data):
        '''
        将list写入txt
        :param data:
        :return:
        '''
        file.write(str(data))
     
    def readListFromStr(str):
        '''
        str -> List
        除去冗余的方法调用
        :param str:
        :return:
        '''
        res,pos = help(str,1)
        res1=[]
        a ='1'
        for ii in res:
            iii=[]
            for i in ii:
                if type(i)==type(a):
                    i = i.replace("'", "")
                    iii.append(i)
                else:
                    iii.append(i)
            res1.append(iii)
        return res1
     
    def help(str,startIndex):
        '''
        单行字符串的读取,形成list
        :param str:
        :return:
        '''
        str = str.replace(" ","") # 将所有空格删去
        res = []
        i = startIndex
        pre = startIndex
        while i <len(str):
            if str[i] == &#39;[&#39;:
                # 将pre-i-2的字符都切片,切split
                if i-2>=pre:
                    slice = str[pre:i-1].split(&#39;,&#39;)
                    for element in slice:
                        res.append(element)
                # 递归调用 加入子list
                child,pos = help(str,i+1)
                res.append(child)
                i = pos # i移动到pos位置,也就是递归的最后一个右括号
                pre = pos + 2 # 右括号之后是, [ 有三个字符,所以要+2至少
            elif str[i] == &#39;]&#39;:
                # 将前面的全部放入列表
                if i-1>=pre:
                    slice = str[pre:i].split(&#39;,&#39;)
                    for element in slice:
                        res.append(element)
                return res,i
            i = i + 1
     
        return res,i
    def get_caozuo(caozuopath):
        with open(caozuopath , &#39;r&#39; , encoding=&#39;utf8&#39;) as f:
            data = f.read()
            return data
    def get_caozuo_name():
        files1 = []
        file_dir = r"C:\Users\ge\Desktop\test1\我的作品\自定义连点器"
        for root, dirs, files in os.walk(file_dir, topdown=False):
            files = files[:-1]
        for i in files:
            files1.append(i[:-4])
        return files1
    print(get_caozuo_name())
    if choose == &#39;循环执行&#39;:
        caozuojiyi = get_caozuo_name()
        while True:
            xunhuan_choose = input(&#39;已存储的操作有:{}\n请输入循环操作的操作名:&#39;.format(caozuojiyi))
            if xunhuan_choose in caozuojiyi:
                break
            else:
                print(&#39;存储库中并无你想要的操作,请重新输入:&#39;)
    登入後複製

    儲存導入功能【升級版】

    上面的功能只能把二維的清單匯入成list類型的資料類型,不利於後面的導入。一旦儲存或匯入的清單達到三維或以上就不適用了。後來我上網搜了半天,終於發現json庫裡面有方法支援以list的形式導出txt並且可以以list的方式讀取。以下是我實現儲存導入的邏輯程式碼:

    導入(功能實作)

    def txttolist(path):
        import json
        b = open(path, "r", encoding=&#39;UTF-8&#39;)
        out = b.read()
        out = json.loads(out)
        return out
    登入後複製
    登入後複製

    導入(邏輯程式碼)

    如果程式記憶體裡已有操作了將提示儲存

        if choose == &#39;导入&#39;:
            if len(step) == 0:
                step = daoru()[0]
            else:
                baocun_choose = input(&#39;此次操作若未保存请先,导入别的操作会覆盖原来的操作,你确定要导入吗?\n请输入“yes”or“no”:\n&#39;)
                while 1:
                    if baocun_choose == &#39;no&#39;:
                        break
                    if baocun_choose == &#39;yes&#39;:
                        print(&#39;你已取消保存&#39;)
                        step = daoru()[0]
                        break
                    else:
                        yorn = input("请输入&#39;yes&#39;or&#39;no&#39;:\n")
    登入後複製

    儲存(功能實作)

    def cunchu():
        yorn = input("执行完毕,是否保存?\n输入&#39;yes&#39;or&#39;no&#39;\n")
        while 1:
            if yorn == &#39;yes&#39;:
                if len(step) == 0:
                    print(&#39;还未记录你任何操作,请添加操作再使用存储功能&#39;)
                else:
                    do_name = input(&#39;请为以上操作命名吧:&#39;)
                    path = r"{}.txt".format(do_name)
                    listtotxt(list=step, path=path)
                break
            if yorn == &#39;no&#39;:
                print(&#39;你已取消存储&#39;)
                break
            else:
                yorn = input("请输入&#39;yes&#39;or&#39;no&#39;:\n")
     
    def listtotxt(list, path):
        import json
        c_list = list
        c_list = json.dumps(c_list)
        &#39;&#39;&#39;将c_list存入文件
        &#39;&#39;&#39;
        a = open(path, "w", encoding=&#39;UTF-8&#39;)
        a.write(c_list)
        a.close()
        print(&#39;已存入txt&#39;)
    登入後複製

    儲存(邏輯程式碼) 

    如果程式記憶體裡還沒有操作會提醒

    #
        if choose == &#39;存储&#39;:
            if len(step) == 0:
                print(&#39;还未记录你任何操作,请添加操作再使用存储功能&#39;)
            else:
                do_name = input(&#39;请为以上操作命名吧:&#39;)
                path = r"{}.txt".format(do_name)
                listtotxt(list=step, path=path)
    登入後複製

    拖拽功能

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

    功能实现

    pyautogui.moveTo(int(i[1][0]), int(i[1][1]))
    pyautogui.dragTo(int(i[2][0]), int(i[2][1]), 1, button=&#39;left&#39;)
    print(f&#39;已执行拖拽动作,拖拽起始位置是X:{int(i[1][0])},Y:{int(i[1][1])},拖拽后的位置是X:{int(i[2][0])},Y:{int(i[2][1])}&#39;)
    登入後複製

    逻辑代码:

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

        if choose == &#39;拖拽&#39;:
            tuozhuai = []
            while 1:
                click_dongzuo = input(&#39;请移动鼠标到目标位置上输入“1”完成移动前的位置输入,输入“0”取消动作&#39;)
                if click_dongzuo == &#39;1&#39;:
                    click_weizhi = get_xy()
                    tuozhuai.append(&#39;拖拽&#39;)
                    tuozhuai.append(click_weizhi)
                    while 1:
                        click_dongzuo = input(&#39;请移动鼠标到目标位置上输入“1”完成移动后的位置输入,输入“0”取消动作&#39;)
                        if click_dongzuo == &#39;1&#39;:
                            click_weizhi = get_xy()
                            tuozhuai.append(click_weizhi)
                            break
                        elif click_dongzuo == &#39;0&#39;:
                            print(&#39;操作已取消&#39;)
                            break
                        else:
                            print(&#39;请输入正确的操作(输入“0”或“1”&#39;)
                    break
                elif click_dongzuo == &#39;0&#39;:
                    print(&#39;操作已取消&#39;)
                    break
                else:
                    print(&#39;请输入正确的操作(输入“0”或“1”&#39;)
            step.append(tuozhuai)
    登入後複製

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

    功能实现

        if choose == &#39;输入&#39;:
            shuru = []
            while 1:
                click_dongzuo = input(&#39;请移动鼠标到你要输入的位置上输入“1”完成动作,输入“0”取消动作&#39;)
                if click_dongzuo == &#39;1&#39;:
                    click_weizhi = get_xy()
                    txt_in = input(&#39;请输入你要在该位置输入的文字:\n&#39;)
                    shuru.append(&#39;输入&#39;)
                    shuru.append(click_weizhi)
                    shuru.append(txt_in)
                    step.append(shuru)
                    break
                elif click_dongzuo == &#39;0&#39;:
                    print(&#39;操作已取消&#39;)
                    break
                else:
                    print(&#39;请输入正确的操作(输入“0”或“1”&#39;)
    登入後複製

    逻辑代码

            if i[0] == &#39;输入&#39;:
                pyautogui.click(int(i[1][0]), int(i[1][1]))
                pyperclip.copy(i[2])
                time.sleep(0.1)
                pyautogui.hotkey(&#39;ctrl&#39;, &#39;v&#39;)
    登入後複製

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

    原理相同,将不再赘述

    功能实现

            if i[0] == &#39;双击&#39;:
                pyautogui.click(int(i[1][0]), int(i[1][1]))
                pyautogui.click(int(i[1][0]), int(i[1][1]))
                print(f&#39;已执行完点击动作,点击坐标位置:X:{int(i[1][0])},Y:{int(i[1][1])}   &#39;)
            if i[0] == &#39;右击&#39;:
                x = int(i[1][0])
                y = int(i[1][1])
                pyautogui.rightClick(x, y)
                print(f&#39;已执行完右击动作,点击坐标位置:X:{x},Y:{y}   &#39;)
            if i[0] == &#39;中击&#39;:
                x = int(i[1][0])
                y = int(i[1][1])
                pyautogui.middleClick(x, y)
                print(f&#39;已执行完中击动作,点击坐标位置:X:{x},Y:{y}   &#39;)
    登入後複製

    逻辑代码

        if choose == &#39;右击&#39;:
            click_r = []
            while 1:
                click_dongzuo = input(&#39;请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作&#39;)
                if click_dongzuo == &#39;1&#39;:
                    click_weizhi = get_xy()
                    click_r.append(&#39;右击&#39;)
                    click_r.append(click_weizhi)
                    step.append(click_r)
                    break
                elif click_dongzuo == &#39;0&#39;:
                    print(&#39;操作已取消&#39;)
                    break
                else:
                    print(&#39;请输入正确的操作(输入“0”或“1”&#39;)
        if choose == &#39;中击&#39;:
            click_m = []
            while 1:
                click_dongzuo = input(&#39;请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作&#39;)
                if click_dongzuo == &#39;1&#39;:
                    click_weizhi = get_xy()
                    click_m.append(&#39;中击&#39;)
                    click_m.append(click_weizhi)
                    step.append(click_m)
                    break
                elif click_dongzuo == &#39;0&#39;:
                    print(&#39;操作已取消&#39;)
                    break
                else:
                    print(&#39;请输入正确的操作(输入“0”或“1”&#39;)
            click_double = []
            while 1:
                click_dongzuo = input(&#39;请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作&#39;)
                if click_dongzuo == &#39;1&#39;:
                    click_weizhi = get_xy()
                    click_double.append(&#39;双击&#39;)
                    click_double.append(click_weizhi)
                    step.append(click_double)
                    break
                elif click_dongzuo == &#39;0&#39;:
                    print(&#39;操作已取消&#39;)
                    break
                else:
                    print(&#39;请输入正确的操作(输入“0”或“1”&#39;)
    登入後複製

    按键功能

    功能实现

            if i[0] == &#39;按键&#39;:
                pyautogui.hotkey(*i[1])
    登入後複製

    逻辑代码

        if choose == &#39;按键&#39;:
            while 1:
                anjian = input(&#39;这是模拟操作键盘的操作(例如复制,输入&#39;ctrl‘ + &#39;c‘):\n&#39;)
                if anjian != &#39;q&#39;:
                    anjian = anjian.split(&#39;+&#39;)
                    anjians = []
                    a = []
                    for an in anjian:
                        an = an.replace("‘", "").replace("&#39;", "").strip()
                        if an in pyautogui.KEYBOARD_KEYS:
                            anjians.append(an)
                            nihaofan = 0
                        else:
                            print(&#39;你的输入不合法&#39;)
                            nihaofan = 1
                            break
                    if nihaofan == 0:
                        a.append(&#39;按键&#39;)
                        a.append(anjians)
                        step.append(a)
                        print(&#39;录入成功&#39;)
                        break
     
                if anjian == &#39;q&#39;:
                    break
    登入後複製

    滚动滚轮功能

    功能实现

            if i[0] == &#39;滚动&#39;:
                import pywinauto.mouse
                x, y = pyautogui.position()
                pywinauto.mouse.scroll((x, y), i[1])  # (1100,300)是初始坐标,1000是滑动距离(可负)
    登入後複製

    逻辑代码

        if choose == &#39;滚动&#39;:
            while 1:
                gundong = []
                try:
                    gundong1 = int(input(&#39;这里是模拟鼠标滚动,请输入你要滚动距离(正数为向上移动,负数为向下移动):\n&#39;))
                    gundong.append(&#39;滚动&#39;)
                    gundong.append(gundong1)
                    step.append(gundong)
                    break
                except:
                    print(&#39;你的输入有误,请重新输入&#39;)
    登入後複製

    查看功能

    def chakan():
        if len(step) == 0:
            print(&#39;暂未录入操作,请先录入操作再查看&#39;)
        zizeng = 1
        for i in step:
            if i[0] == &#39;点击&#39;:
                x = int(i[1][0])
                y = int(i[1][1])
                print(f&#39;第{zizeng}步:\n执行点击动作,点击坐标位置:X:{x},Y:{y}   &#39;)
            if i[0] == &#39;延时&#39;:
                t = int(i[1])
                print(f&#39;第{zizeng}步:\n执行延时动作,延时时长:{t}秒&#39;)
            if i[0] == &#39;连点&#39;:
                if i[2] == &#39;连点次数&#39;:
                    print(f&#39;第{zizeng}步:\n执行连点操作,你选择的是{i[2]},连点次数是{i[4]}&#39;)
                if i[2] == &#39;连点时长&#39;:
                    print(f&#39;第{zizeng}步:\n执行连点操作,你选择的是{i[2]},连点时长是{i[4]}秒&#39;)
            if i[0] == &#39;拖拽&#39;:
                print(
                    f&#39;第{zizeng}步:\n执行拖拽动作,拖拽起始位置是X:{int(i[1][0])},Y:{int(i[1][1])},拖拽后的位置是X:{int(i[2][0])},Y:{int(i[2][1])}&#39;)
            if i[0] == &#39;双击&#39;:
                print(f&#39;第{zizeng}步:\n执行点击动作,点击坐标位置:X:{int(i[1][0])},Y:{int(i[1][1])}   &#39;)
     
            if i[0] == &#39;按键&#39;:
                print(f&#39;第{zizeng}步:\n执行按键动作,将同时按下”{i[1]}“键&#39;)
            zizeng += 1
    登入後複製

    执行功能

    执行后将询问是否保存

    def zhixing(step):
        for i in step:
            if i[0] == '点击':
                x = int(i[1][0])
                y = int(i[1][1])
                pyautogui.click(x, y)
                print(f'已执行完点击动作,点击坐标位置:X:{x},Y:{y}   ')
            if i[0] == '延时':
                t = int(i[1])
                timer(t)
                print(f'已执行完延时动作,延时时长:{t}秒')
            if i[0] == '连点':
                if i[2] == '连点次数':
                    clicker_cishu(int(i[3]), int(i[1][0]), int(i[1][1]), int(i[4]))
                    print(f'已执行完连点操作,你选择的是{i[2]},连点次数是{i[4]}')
                if i[2] == '连点时长':
                    clicker_time(int(i[3]), int(i[1][0]), int(i[1][1]), int(i[4]))
                    print(f'已执行完连点操作,你选择的是{i[2]},连点时长是{i[4]}秒')
            if i[0] == '拖拽':
                pyautogui.moveTo(int(i[1][0]), int(i[1][1]))
                pyautogui.dragTo(int(i[2][0]), int(i[2][1]), 1, button='left')
                print(f'已执行拖拽动作,拖拽起始位置是X:{int(i[1][0])},Y:{int(i[1][1])},拖拽后的位置是X:{int(i[2][0])},Y:{int(i[2][1])}')
            if i[0] == '双击':
                pyautogui.click(int(i[1][0]), int(i[1][1]))
                pyautogui.click(int(i[1][0]), int(i[1][1]))
                print(f'已执行完点击动作,点击坐标位置:X:{int(i[1][0])},Y:{int(i[1][1])}   ')
            if i[0] == &#39;输入&#39;:
                pyautogui.click(int(i[1][0]), int(i[1][1]))
                pyperclip.copy(i[2])
                time.sleep(0.1)
                pyautogui.hotkey(&#39;ctrl&#39;, &#39;v&#39;)
            if i[0] == &#39;按键&#39;:
                pyautogui.hotkey(*i[1])
            if i[0] == '右击':
                x = int(i[1][0])
                y = int(i[1][1])
                pyautogui.rightClick(x, y)
                print(f'已执行完右击动作,点击坐标位置:X:{x},Y:{y}   ')
            if i[0] == '中击':
                x = int(i[1][0])
                y = int(i[1][1])
                pyautogui.middleClick(x, y)
                print(f'已执行完中击动作,点击坐标位置:X:{x},Y:{y}   ')
            if i[0] == &#39;滚动&#39;:
                import pywinauto.mouse
                x, y = pyautogui.position()
                pywinauto.mouse.scroll((x, y), i[1])  # (1100,300)是初始坐标,1000是滑动距离(可负)
    登入後複製
        if choose == &#39;执行&#39;:
            if len(step) == 0:
                print(&#39;你还未记录任何操作,请至少记录了一个操作再执行&#39;)
            else:
                zhixing(step)
                cunchu()
    登入後複製

    逻辑判断功能板块

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

    判断功能

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

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

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

    判断功能的逻辑代码

        if choose == &#39;判断&#39;:
            if len(panduans) == 0:
                tuichu = 0
                panduan = input(&#39;此功能的实现是基于颜色的RBG值来判断程序所要要执行的步骤块。\n现在,请选择你的‘先执行步骤块等待条件触发&#39;或是‘直接等待条件触发&#39;的操作:(输入"步骤块"或"等待")\n&#39;)
                if panduan == &#39;如果&#39;:
                    panduan_if = []
                    while 1:
                        click_dongzuo = input(&#39;请移动鼠标到目标位置上吸取颜色,输入“1”完成动作,输入“0”取消动作&#39;)
                        if click_dongzuo == &#39;1&#39;:
                            xy = get_xy()
                            click_color = GetColor(xy)
                            panduan_yn = input(f&#39;这个位置的RGB为:{click_color},是否确定为下一步骤块的判断根据?(输入"yes"or"no")\n&#39;)
                            while 1:
                                if panduan_yn == &#39;yes&#39;:
                                    get_caozuo_name()
                                    print(f&#39;请选择满足当颜色为{click_color}时要执行的步骤包:&#39;)
                                    steps, steps_name = daoru()
                                    xunhuan_yn = input(&#39;这个步骤块是否循环执行至下一条件触发?(输入"yes"or"no")\n&#39;)
                                    while 1:
                                        if xunhuan_yn == &#39;yes&#39;:
                                            panduan_if.append(&#39;如果&#39;)
                                            panduan_if.append(xy)
                                            panduan_if.append(click_color)
                                            panduan_if.append(steps_name)
                                            panduan_if.append(&#39;循环&#39;)
                                            panduan_if.append(steps)
                                            panduans.append(panduan_if)
                                            print(&#39;添加成功,该步骤包将会循环&#39;)
                                            break
                                        elif xunhuan_yn == &#39;no&#39;:
                                            panduan_if.append(&#39;如果&#39;)
                                            panduan_if.append(xy)
                                            panduan_if.append(click_color)
                                            panduan_if.append(steps_name)
                                            panduan_if.append(&#39;不循环&#39;)
                                            panduan_if.append(steps)
                                            panduans.append(panduan_if)
                                            print(&#39;添加成功,该步骤包将只执行一次&#39;)
                                            break
                                        else:
                                            xunhuan_yn = input(&#39;你的输入有误,请输入"yes"or"no":&#39;)
                                    tuichu = 1
                                    break
                                if panduan_yn == &#39;no&#39;:
                                    print(&#39;请重新选择&#39;)
                                    break
                                else:
                                    panduan_yn = input(&#39;你的输入有误,请输入"yes"or"no"&#39;)
                            if tuichu == 1:
                                break
                        elif click_dongzuo == &#39;0&#39;:
                            print(&#39;操作已取消&#39;)
                            break
                        else:
                            print(&#39;请输入正确的操作(输入“0”或“1”)&#39;)
                if panduan == &#39;步骤块&#39;:
                    panduan_step = []
                    steps, steps_name = daoru()
                    xunhuan_yn = input(&#39;这个步骤块是否循环执行直至条件触发?(输入"yes"or"no")\n&#39;)
                    while 1:
                        if xunhuan_yn == &#39;yes&#39;:
                            panduan_step.append(&#39;步骤块&#39;)
                            panduan_step.append(&#39;循环&#39;)
                            panduan_step.append(steps_name)
                            panduan_step.append(steps)
                            panduans.append(panduan_step)
                            break
                        elif xunhuan_yn == &#39;no&#39;:
                            panduan_step.append(&#39;步骤块&#39;)
                            panduan_step.append(&#39;不循环&#39;)
                            panduan_step.append(steps_name)
                            panduan_step.append(steps)
                            panduans.append(panduan_step)
                            break
                        else:
                            xunhuan_yn = input(&#39;你的输入有误,请输入"yes"or"no":&#39;)
                if panduan == &#39;等待&#39;:
                    panduan_if = []
                    print(&#39;你选择了等待,程序将时刻检测目标位置的颜色以执行接下来的步骤块&#39;)
                    panduan_if.append(&#39;等待&#39;)
                    panduans.append(panduan_if)
                if panduan != &#39;步骤块&#39; and panduan != &#39;如果&#39; and panduan != &#39;等待&#39;:
                    print(&#39;你的输入有误&#39;)
            if len(panduans) > 0:
                print(&#39;你一录入了至少一个逻辑判断,请选择继续选择目标位置的颜色来触发接下来你选择的步骤块&#39;)
                panduan_if = []
                while 1:
                    click_dongzuo = input(&#39;请移动鼠标到目标位置上吸取颜色,输入“1”完成动作,输入“0”取消动作&#39;)
                    if click_dongzuo == &#39;1&#39;:
                        xy = get_xy()
                        click_color = GetColor(xy)
                        panduan_yn = input(f&#39;这个位置的RGB为:{click_color},是否确定为下一步骤块的判断根据?(输入"yes"or"no")\n&#39;)
                        while 1:
                            if panduan_yn == &#39;yes&#39;:
                                get_caozuo_name()
                                print(f&#39;请选择满足当颜色为{click_color}时要执行的步骤包:&#39;)
                                steps, steps_name = daoru()
                                xunhuan_yn = input(&#39;这个步骤块是否循环执行直至条件触发?(输入"yes"or"no")\n&#39;)
                                while 1:
                                    if xunhuan_yn == &#39;yes&#39;:
                                        panduan_if.append(&#39;如果&#39;)
                                        panduan_if.append(xy)
                                        panduan_if.append(click_color)
                                        panduan_if.append(steps_name)
                                        panduan_if.append(&#39;循环&#39;)
                                        panduan_if.append(steps)
                                        panduans.append(panduan_if)
                                        print(&#39;添加成功,该步骤包将会循环&#39;)
                                        break
                                    elif xunhuan_yn == &#39;no&#39;:
                                        panduan_if.append(&#39;如果&#39;)
                                        panduan_if.append(xy)
                                        panduan_if.append(click_color)
                                        panduan_if.append(steps_name)
                                        panduan_if.append(&#39;不循环&#39;)
                                        panduan_if.append(steps)
                                        panduans.append(panduan_if)
                                        print(&#39;添加成功,该步骤包将只执行一次&#39;)
                                        break
                                    else:
                                        xunhuan_yn = input(&#39;你的输入有误,请输入"yes"or"no":&#39;)
                                tuichu = 1
                                break
                            if panduan_yn == &#39;no&#39;:
                                print(&#39;请重新选择&#39;)
                                break
                            else:
                                panduan_yn = input(&#39;你的输入有误,请输入"yes"or"no"&#39;)
                        if tuichu == 1:
                            break
                    elif click_dongzuo == &#39;0&#39;:
                        print(&#39;操作已取消&#39;)
                        break
                    else:
                        print(&#39;请输入正确的操作(输入“0”或“1”)&#39;)
    登入後複製

    逻辑执行功能的实现

        if choose == &#39;逻辑执行&#39;:
            print(&#39;这里是逻辑执行库,所有的逻辑判断都会存储到这里&#39;)
            print(panduans)
            xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(&#39;等待&#39;, &#39;1&#39;, &#39;循环&#39;))
            xiancheng.setDaemon(True)
            xiancheng.start()
            for pan in panduans:
                state = &#39;未触发&#39;
                if pan[0] == &#39;如果&#39;:
                    print(pan[5])
                    print(len(pan[5]))
                    bu = str(pan[5])
                    print(bu)
                    bu = readListFromStr(bu)
                    zhixing(bu)
                    print(bu)
                    if state == &#39;未触发&#39;:
                        if pan[4] == &#39;循环&#39;:
                            rgb = pan[2]
                            rgb_xy = pan[1]
                            _thread.start_new_thread(jianshi, ())
                            while 1:
                                if state == &#39;触发&#39;:
                                    xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[3], pan[5], &#39;循环&#39;))
                                    xiancheng.start()
                                    state = &#39;未触发&#39;
                                    break
                        if pan[4] == &#39;不循环&#39;:
                            rgb = pan[2]
                            rgb_xy = pan[1]
                            _thread.start_new_thread(jianshi, ())
                            while 1:
                                if state == &#39;触发&#39;:
                                    xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[3], pan[5], &#39;不循环&#39;))
                                    xiancheng.start()
                                    state = &#39;未触发&#39;
                                    break
                if pan[0] == &#39;步骤块&#39;:
                    stop_thread(xiancheng)
                    if pan[1] == &#39;循环&#39;:
                        xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[2], pan[3], &#39;循环&#39;))
                        xiancheng.start()
                    if pan[1] == &#39;不循环&#39;:
                        xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[2], pan[3], &#39;不循环&#39;))
                        xiancheng.start()
                if pan[0] == &#39;等待&#39;:
                    print(&#39;程序正在监测目标位置RGB值&#39;)
            print(&#39;逻辑执行已全部执行完毕&#39;)
            break
    登入後複製

    逻辑块存储功能的实现

    def listtotxt(list, path):
        import json
        c_list = list
        c_list = json.dumps(c_list)
        &#39;&#39;&#39;将c_list存入文件
        &#39;&#39;&#39;
        a = open(path, "w", encoding=&#39;UTF-8&#39;)
        a.write(c_list)
        a.close()
        print(&#39;已存入txt&#39;)
    登入後複製

    逻辑块存储逻辑代码

        if choose == &#39;逻辑块存储&#39;:
            yorn = input("确定保存?\n输入&#39;yes&#39;or&#39;no&#39;\n")
            while 1:
                if yorn == &#39;yes&#39;:
                    if len(panduans) == 0:
                        print(&#39;还未记录你任何操作,请添加操作再使用逻辑块存储功能&#39;)
                    else:
                        do_name = input(&#39;请为以上操作命名吧:&#39;)
                        if &#39;逻辑块存储&#39; in do_name:
                            do_name = input(&#39;抱歉,你的命名里不允许包含”逻辑块存储“,请重新命名&#39;)
                        else:
                            path = r"{}逻辑块存储.txt".format(do_name)
                            listtotxt(list=panduans, path=path)
                    break
                if yorn == &#39;no&#39;:
                    print(&#39;你已取消存储&#39;)
                    break
                else:
                    yorn = input("请输入&#39;yes&#39;or&#39;no&#39;:\n")
    登入後複製

    逻辑块导入功能的实现

    def txttolist(path):
        import json
        b = open(path, "r", encoding=&#39;UTF-8&#39;)
        out = b.read()
        out = json.loads(out)
        return out
    登入後複製
    登入後複製

    逻辑块导入逻辑代码

        if choose == &#39;逻辑块导入&#39;:
            caozuojiyi = get_caozuokuai_name()
            while True:
                xunhuan_choose = input(&#39;已存储的操作有:{}\n请输入导入操作的操作名:&#39;.format(caozuojiyi))
                if xunhuan_choose in caozuojiyi:
                    break
                else:
                    print(&#39;逻辑块存储库中并无你想要的操作,请重新输入:&#39;)
            caozuopath = r"{}逻辑块存储.txt".format(xunhuan_choose)
            panduans = txttolist(path=caozuopath)
    登入後複製

    完整代码

    import threading
    import pyautogui
    from ctypes import *
    import time
    import os, sys
    import pyperclip
    import inspect
    import ctypes
    import _thread
     
     
    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(threa):
        _async_raise(threa.ident, SystemExit)
     
     
    def get_caozuo_name():
        dirname, filename = os.path.split(os.path.abspath(sys.argv[0]))
        files1 = []
        file_dir = r"{}".format(os.path.realpath(sys.argv[0])[:-13])
        for root, dirs, files in os.walk(file_dir, topdown=False):
            files = files[:-1]
        for i in files:
            if '.txt' in i:
                files1.append(i[:-4])
        return files1
     
     
    def get_caozuokuai_name():
        dirname, filename = os.path.split(os.path.abspath(sys.argv[0]))
        files1 = []
        file_dir = r"{}".format(os.path.realpath(sys.argv[0])[:-13])
        for root, dirs, files in os.walk(file_dir, topdown=False):
            files = files[:-1]
        for i in files:
            if '逻辑块存储.txt' in i:
                files1.append(i[:-9])
        return files1
     
     
    def writeList2txt(file, data):
        '''
        将list写入txt
        :param data:
        :return:
        '''
        file.write(str(data), encoding='uft8')
     
     
    def readListFromStr(str):
        '''
        str -> List
        除去冗余的方法调用
        :param str:
        :return:
        '''
        res, pos = help(str, 1)
        res1 = []
        a = '1'
        for ii in res:
            iii = []
            for i in ii:
                if type(i) == type(a):
                    i = i.replace("'", "")
                    iii.append(i)
                else:
                    iii.append(i)
            res1.append(iii)
        return res1
     
     
    def help(str, startIndex):
        '''
        单行字符串的读取,形成list
        :param str:
        :return:
        '''
        str = str.replace(" ", "")  # 将所有空格删去
        res = []
        i = startIndex
        pre = startIndex
        while i < len(str):
            if str[i] == '[':
                # 将pre-i-2的字符都切片,切split
                if i - 2 >= pre:
                    slice = str[pre:i - 1].split(',')
                    for element in slice:
                        res.append(element)
                # 递归调用 加入子list
                child, pos = help(str, i + 1)
                res.append(child)
                i = pos  # i移动到pos位置,也就是递归的最后一个右括号
                pre = pos + 2  # 右括号之后是, [ 有三个字符,所以要+2至少
            elif str[i] == ']':
                # 将前面的全部放入列表
                if i - 1 >= pre:
                    slice = str[pre:i].split(',')
                    for element in slice:
                        res.append(element)
                return res, i
            i = i + 1
     
        return res, i
     
     
    def get_caozuo(caozuopath):
        with open(caozuopath, 'r', encoding='utf8') as f:
            data = f.read()
            return data
     
     
    def get_xy():
        x, y = pyautogui.position()
        return [x, y]
     
     
    def GetColor(xy):
        x = xy[0]
        y = xy[1]
        r = 0
        g = 0
        b = 0
        try:
            gdi32 = windll.gdi32
            user32 = windll.user32
            hdc = user32.GetDC(None)  # 获取颜色值
            pixel = gdi32.GetPixel(hdc, x, y)  # 提取RGB值
            r = pixel & 0x0000ff
            g = (pixel & 0x00ff00) >> 8
            b = pixel >> 16
        except KeyboardInterrupt:
            print('\n')
        return [r, g, b]
     
     
    def timer(timex):
        time.sleep(timex)
     
     
    def clicker_cishu(cishu, x, y, pinlv):
        for a in range(cishu):
            pyautogui.click(x, y)
            time.sleep(pinlv)
     
     
    def clicker_time(shijian, x, y, pinlv):
        start = time.time()
        while True:
            pyautogui.click(x, y)
            time.sleep(pinlv)
            end = time.time()
            shijian1 = end - start
            if shijian1 >= shijian:
                break
     
     
    def zhixing(step):
        for i in step:
            if i[0] == '点击':
                x = int(i[1][0])
                y = int(i[1][1])
                pyautogui.click(x, y)
                print(f'已执行完点击动作,点击坐标位置:X:{x},Y:{y}   ')
            if i[0] == '延时':
                t = int(i[1])
                timer(t)
                print(f'已执行完延时动作,延时时长:{t}秒')
            if i[0] == '连点':
                if i[2] == '连点次数':
                    clicker_cishu(int(i[3]), int(i[1][0]), int(i[1][1]), int(i[4]))
                    print(f'已执行完连点操作,你选择的是{i[2]},连点次数是{i[4]}')
                if i[2] == '连点时长':
                    clicker_time(int(i[3]), int(i[1][0]), int(i[1][1]), int(i[4]))
                    print(f'已执行完连点操作,你选择的是{i[2]},连点时长是{i[4]}秒')
            if i[0] == '拖拽':
                pyautogui.moveTo(int(i[1][0]), int(i[1][1]))
                pyautogui.dragTo(int(i[2][0]), int(i[2][1]), 1, button='left')
                print(f'已执行拖拽动作,拖拽起始位置是X:{int(i[1][0])},Y:{int(i[1][1])},拖拽后的位置是X:{int(i[2][0])},Y:{int(i[2][1])}')
            if i[0] == '双击':
                pyautogui.click(int(i[1][0]), int(i[1][1]))
                pyautogui.click(int(i[1][0]), int(i[1][1]))
                print(f'已执行完点击动作,点击坐标位置:X:{int(i[1][0])},Y:{int(i[1][1])}   ')
            if i[0] == &#39;输入&#39;:
                pyautogui.click(int(i[1][0]), int(i[1][1]))
                pyperclip.copy(i[2])
                time.sleep(0.1)
                pyautogui.hotkey(&#39;ctrl&#39;, &#39;v&#39;)
            if i[0] == &#39;按键&#39;:
                pyautogui.hotkey(*i[1])
            if i[0] == '右击':
                x = int(i[1][0])
                y = int(i[1][1])
                pyautogui.rightClick(x, y)
                print(f'已执行完右击动作,点击坐标位置:X:{x},Y:{y}   ')
            if i[0] == '中击':
                x = int(i[1][0])
                y = int(i[1][1])
                pyautogui.middleClick(x, y)
                print(f'已执行完中击动作,点击坐标位置:X:{x},Y:{y}   ')
            if i[0] == &#39;滚动&#39;:
                import pywinauto.mouse
                x, y = pyautogui.position()
                pywinauto.mouse.scroll((x, y), i[1])  # (1100,300)是初始坐标,1000是滑动距离(可负)
     
     
    def cunchu():
        yorn = input("执行完毕,是否保存?\n输入'yes'or'no'\n")
        while 1:
            if yorn == 'yes':
                if len(step) == 0:
                    print('还未记录你任何操作,请添加操作再使用存储功能')
                else:
                    do_name = input('请为以上操作命名吧:')
                    path = r"{}.txt".format(do_name)
                    listtotxt(list=step, path=path)
                break
            if yorn == 'no':
                print('你已取消存储')
                break
            else:
                yorn = input("请输入'yes'or'no':\n")
     
     
    def chakan():
        if len(step) == 0:
            print(&#39;暂未录入操作,请先录入操作再查看&#39;)
        zizeng = 1
        for i in step:
            if i[0] == &#39;点击&#39;:
                x = int(i[1][0])
                y = int(i[1][1])
                print(f&#39;第{zizeng}步:\n执行点击动作,点击坐标位置:X:{x},Y:{y}   &#39;)
            if i[0] == &#39;延时&#39;:
                t = int(i[1])
                print(f&#39;第{zizeng}步:\n执行延时动作,延时时长:{t}秒&#39;)
            if i[0] == &#39;连点&#39;:
                if i[2] == &#39;连点次数&#39;:
                    print(f&#39;第{zizeng}步:\n执行连点操作,你选择的是{i[2]},连点次数是{i[4]}&#39;)
                if i[2] == &#39;连点时长&#39;:
                    print(f&#39;第{zizeng}步:\n执行连点操作,你选择的是{i[2]},连点时长是{i[4]}秒&#39;)
            if i[0] == &#39;拖拽&#39;:
                print(
                    f&#39;第{zizeng}步:\n执行拖拽动作,拖拽起始位置是X:{int(i[1][0])},Y:{int(i[1][1])},拖拽后的位置是X:{int(i[2][0])},Y:{int(i[2][1])}&#39;)
            if i[0] == &#39;双击&#39;:
                print(f&#39;第{zizeng}步:\n执行点击动作,点击坐标位置:X:{int(i[1][0])},Y:{int(i[1][1])}   &#39;)
     
            if i[0] == &#39;按键&#39;:
                print(f&#39;第{zizeng}步:\n执行按键动作,将同时按下”{i[1]}“键&#39;)
            zizeng += 1
     
     
    def daoru():
        caozuojiyi = get_caozuo_name()
        while True:
            xunhuan_choose = input('已存储的操作有:{}\n请输入导入操作的操作名:'.format(caozuojiyi))
            if xunhuan_choose in caozuojiyi:
                break
            else:
                print('存储库中并无你想要的操作,请重新输入:')
        caozuopath = r'{}.txt'.format(xunhuan_choose)
        step1 = txttolist(caozuopath)
        print(step1)
        return [step1, xunhuan_choose]
     
     
    def jianshi():
        global state, rgb, rgb_xy, xiancheng
        while 1:
            aa = GetColor(rgb_xy)
            if aa == rgb:
                try:
                    stop_thread(xiancheng)
                finally:
     
                    state = '触发'
                    print(f'检测到{rgb_xy}位置的RGB值变为{aa}')
                    break
     
     
    def zhixingbuzhoukuai(buzhou, bu, xunhuanyn):
        global state
        print(f'正在执行"{buzhou}"代码块的操作')
        state = '未触发'
        if bu == '1':
            while 1:
                if state == '触发':
                    break
                if state == '未触发':
                    timer(0.1)
        elif xunhuanyn == '循环':
            while 1:
                if state == '触发':
                    break
                if state == '未触发':
                    zhixing(bu)
        elif xunhuanyn == '不循环':
            zhixing(bu)
     
     
    def listtotxt(list, path):
        import json
        c_list = list
        c_list = json.dumps(c_list)
        &#39;&#39;&#39;将c_list存入文件
        &#39;&#39;&#39;
        a = open(path, "w", encoding=&#39;UTF-8&#39;)
        a.write(c_list)
        a.close()
        print(&#39;已存入txt&#39;)
     
     
    def txttolist(path):
        import json
        b = open(path, "r", encoding=&#39;UTF-8&#39;)
        out = b.read()
        out = json.loads(out)
        return out
     
     
    rgb_xy = []
    rgb = []
    state = '未触发'
    panduans = []
    step = []
    while True:
        choose = input('请输入你需要使用的功能:')
        if choose == '点击':
            click = []
            while 1:
                click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
                if click_dongzuo == '1':
                    click_weizhi = get_xy()
                    click.append('点击')
                    click.append(click_weizhi)
                    step.append(click)
                    break
                elif click_dongzuo == '0':
                    print('操作已取消')
                    break
                else:
                    print('请输入正确的操作(输入“0”或“1”')
        if choose == '延时':
            while 1:
                timerr = []
                try:
                    timex = int(input('请输入延时时间:'))
                    timerr.append('延时')
                    timerr.append(timex)
                    step.append(timerr)
                    break
                except:
                    print('延时失败/n请输入正确的延时时间')
                    continue
        if choose == '连点':
            click_liandian = []
            while 1:
                click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
                if click_dongzuo == '1':
                    click_weizhi = get_xy()
                    click_liandian.append('连点')
                    click_liandian.append(click_weizhi)
                    break
                elif click_dongzuo == '0':
                    print('操作已取消')
                    break
                else:
                    print('请输入正确的操作(输入“0”或“1”')
            click_pinlv = float(input('请输入连点频率:'))
            while 1:
                click_stop_choose = input('“连点次数”or“连点时长”')
                if click_stop_choose == '连点次数':
                    click_cishu = int(input('请输入连点次数:'))
                    click_liandian.append('连点次数')
                    click_liandian.append(click_cishu)
                    click_liandian.append(click_pinlv)
                    step.append(click_liandian)
                    print(click_liandian)
                    print(step)
                    break
                if click_stop_choose == '连点时长':
                    click_shichang = int(input('请输入连点时长(秒):'))
                    click_liandian.append('连点时长')
                    click_liandian.append(click_shichang)
                    step.append(click_liandian)
                    click_liandian.append(click_pinlv)
                    print(click_liandian)
                    print(step)
                    break
                else:
                    continue
        if choose == &#39;存储&#39;:
            if len(step) == 0:
                print(&#39;还未记录你任何操作,请添加操作再使用存储功能&#39;)
            else:
                do_name = input(&#39;请为以上操作命名吧:&#39;)
                path = r"{}.txt".format(do_name)
                listtotxt(list=step, path=path)
        if choose == &#39;拖拽&#39;:
            tuozhuai = []
            while 1:
                click_dongzuo = input(&#39;请移动鼠标到目标位置上输入“1”完成移动前的位置输入,输入“0”取消动作&#39;)
                if click_dongzuo == &#39;1&#39;:
                    click_weizhi = get_xy()
                    tuozhuai.append(&#39;拖拽&#39;)
                    tuozhuai.append(click_weizhi)
                    while 1:
                        click_dongzuo = input(&#39;请移动鼠标到目标位置上输入“1”完成移动后的位置输入,输入“0”取消动作&#39;)
                        if click_dongzuo == &#39;1&#39;:
                            click_weizhi = get_xy()
                            tuozhuai.append(click_weizhi)
                            break
                        elif click_dongzuo == &#39;0&#39;:
                            print(&#39;操作已取消&#39;)
                            break
                        else:
                            print(&#39;请输入正确的操作(输入“0”或“1”&#39;)
                    break
                elif click_dongzuo == &#39;0&#39;:
                    print(&#39;操作已取消&#39;)
                    break
                else:
                    print(&#39;请输入正确的操作(输入“0”或“1”&#39;)
            step.append(tuozhuai)
        if choose == '循环执行':
            while 1:
                xunhuan_cishu_zhixing = 0
                xunhuan_cishu = input('请输入循环次数(如要无限循环请输入"无限"):')
                if xunhuan_cishu == '无限':
                    while True:
                        zhixing(step)
                if xunhuan_cishu.isdigit():
     
                    for i in range(int(xunhuan_cishu)):
                        xunhuan_cishu_zhixing += 1
                        zhixing(step)
                        print(f'已完成{xunhuan_cishu_zhixing}次循环')
                    break
                else:
                    print('你的输入有误,请重新输入:')
        if choose == &#39;导入&#39;:
            if len(step) == 0:
                step = daoru()[0]
            else:
                baocun_choose = input(&#39;此次操作若未保存请先,导入别的操作会覆盖原来的操作,你确定要导入吗?\n请输入“yes”or“no”:\n&#39;)
                while 1:
                    if baocun_choose == &#39;no&#39;:
                        break
                    if baocun_choose == &#39;yes&#39;:
                        print(&#39;你已取消保存&#39;)
                        step = daoru()[0]
                        break
                    else:
                        yorn = input("请输入&#39;yes&#39;or&#39;no&#39;:\n")
        if choose == &#39;输入&#39;:
            shuru = []
            while 1:
                click_dongzuo = input(&#39;请移动鼠标到你要输入的位置上输入“1”完成动作,输入“0”取消动作&#39;)
                if click_dongzuo == &#39;1&#39;:
                    click_weizhi = get_xy()
                    txt_in = input(&#39;请输入你要在该位置输入的文字:\n&#39;)
                    shuru.append(&#39;输入&#39;)
                    shuru.append(click_weizhi)
                    shuru.append(txt_in)
                    step.append(shuru)
                    break
                elif click_dongzuo == &#39;0&#39;:
                    print(&#39;操作已取消&#39;)
                    break
                else:
                    print(&#39;请输入正确的操作(输入“0”或“1”&#39;)
        if choose == &#39;按键&#39;:
            while 1:
                anjian = input(&#39;这是模拟操作键盘的操作(例如复制,输入&#39;ctrl‘ + &#39;c‘):\n&#39;)
                if anjian != &#39;q&#39;:
                    anjian = anjian.split(&#39;+&#39;)
                    anjians = []
                    a = []
                    for an in anjian:
                        an = an.replace("‘", "").replace("&#39;", "").strip()
                        if an in pyautogui.KEYBOARD_KEYS:
                            anjians.append(an)
                            nihaofan = 0
                        else:
                            print(&#39;你的输入不合法&#39;)
                            nihaofan = 1
                            break
                    if nihaofan == 0:
                        a.append(&#39;按键&#39;)
                        a.append(anjians)
                        step.append(a)
                        print(&#39;录入成功&#39;)
                        break
     
                if anjian == &#39;q&#39;:
                    break
        if choose == '双击':
            click_double = []
            while 1:
                click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
                if click_dongzuo == '1':
                    click_weizhi = get_xy()
                    click_double.append('双击')
                    click_double.append(click_weizhi)
                    step.append(click_double)
                    break
                elif click_dongzuo == '0':
                    print('操作已取消')
                    break
                else:
                    print('请输入正确的操作(输入“0”或“1”')
        if choose == &#39;滚动&#39;:
            while 1:
                gundong = []
                try:
                    gundong1 = int(input(&#39;这里是模拟鼠标滚动,请输入你要滚动距离(正数为向上移动,负数为向下移动):\n&#39;))
                    gundong.append(&#39;滚动&#39;)
                    gundong.append(gundong1)
                    step.append(gundong)
                    break
                except:
                    print(&#39;你的输入有误,请重新输入&#39;)
        if choose == '查看':
            chakan()
        if choose == '右击':
            click_r = []
            while 1:
                click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
                if click_dongzuo == '1':
                    click_weizhi = get_xy()
                    click_r.append('右击')
                    click_r.append(click_weizhi)
                    step.append(click_r)
                    break
                elif click_dongzuo == '0':
                    print('操作已取消')
                    break
                else:
                    print('请输入正确的操作(输入“0”或“1”')
        if choose == '中击':
            click_m = []
            while 1:
                click_dongzuo = input('请移动鼠标到目标位置上输入“1”完成动作,输入“0”取消动作')
                if click_dongzuo == '1':
                    click_weizhi = get_xy()
                    click_m.append('中击')
                    click_m.append(click_weizhi)
                    step.append(click_m)
                    break
                elif click_dongzuo == '0':
                    print('操作已取消')
                    break
                else:
                    print('请输入正确的操作(输入“0”或“1”')
        if choose == &#39;执行&#39;:
            if len(step) == 0:
                print(&#39;你还未记录任何操作,请至少记录了一个操作再执行&#39;)
            else:
                zhixing(step)
                cunchu()
        if choose == &#39;判断&#39;:
            if len(panduans) == 0:
                tuichu = 0
                panduan = input(&#39;此功能的实现是基于颜色的RBG值来判断程序所要要执行的步骤块。\n现在,请选择你的‘先执行步骤块等待条件触发&#39;或是‘直接等待条件触发&#39;的操作:(输入"步骤块"或"等待")\n&#39;)
                if panduan == &#39;如果&#39;:
                    panduan_if = []
                    while 1:
                        click_dongzuo = input(&#39;请移动鼠标到目标位置上吸取颜色,输入“1”完成动作,输入“0”取消动作&#39;)
                        if click_dongzuo == &#39;1&#39;:
                            xy = get_xy()
                            click_color = GetColor(xy)
                            panduan_yn = input(f&#39;这个位置的RGB为:{click_color},是否确定为下一步骤块的判断根据?(输入"yes"or"no")\n&#39;)
                            while 1:
                                if panduan_yn == &#39;yes&#39;:
                                    get_caozuo_name()
                                    print(f&#39;请选择满足当颜色为{click_color}时要执行的步骤包:&#39;)
                                    steps, steps_name = daoru()
                                    xunhuan_yn = input(&#39;这个步骤块是否循环执行至下一条件触发?(输入"yes"or"no")\n&#39;)
                                    while 1:
                                        if xunhuan_yn == &#39;yes&#39;:
                                            panduan_if.append(&#39;如果&#39;)
                                            panduan_if.append(xy)
                                            panduan_if.append(click_color)
                                            panduan_if.append(steps_name)
                                            panduan_if.append(&#39;循环&#39;)
                                            panduan_if.append(steps)
                                            panduans.append(panduan_if)
                                            print(&#39;添加成功,该步骤包将会循环&#39;)
                                            break
                                        elif xunhuan_yn == &#39;no&#39;:
                                            panduan_if.append(&#39;如果&#39;)
                                            panduan_if.append(xy)
                                            panduan_if.append(click_color)
                                            panduan_if.append(steps_name)
                                            panduan_if.append(&#39;不循环&#39;)
                                            panduan_if.append(steps)
                                            panduans.append(panduan_if)
                                            print(&#39;添加成功,该步骤包将只执行一次&#39;)
                                            break
                                        else:
                                            xunhuan_yn = input(&#39;你的输入有误,请输入"yes"or"no":&#39;)
                                    tuichu = 1
                                    break
                                if panduan_yn == &#39;no&#39;:
                                    print(&#39;请重新选择&#39;)
                                    break
                                else:
                                    panduan_yn = input(&#39;你的输入有误,请输入"yes"or"no"&#39;)
                            if tuichu == 1:
                                break
                        elif click_dongzuo == &#39;0&#39;:
                            print(&#39;操作已取消&#39;)
                            break
                        else:
                            print(&#39;请输入正确的操作(输入“0”或“1”)&#39;)
                if panduan == &#39;步骤块&#39;:
                    panduan_step = []
                    steps, steps_name = daoru()
                    xunhuan_yn = input(&#39;这个步骤块是否循环执行直至条件触发?(输入"yes"or"no")\n&#39;)
                    while 1:
                        if xunhuan_yn == &#39;yes&#39;:
                            panduan_step.append(&#39;步骤块&#39;)
                            panduan_step.append(&#39;循环&#39;)
                            panduan_step.append(steps_name)
                            panduan_step.append(steps)
                            panduans.append(panduan_step)
                            break
                        elif xunhuan_yn == &#39;no&#39;:
                            panduan_step.append(&#39;步骤块&#39;)
                            panduan_step.append(&#39;不循环&#39;)
                            panduan_step.append(steps_name)
                            panduan_step.append(steps)
                            panduans.append(panduan_step)
                            break
                        else:
                            xunhuan_yn = input(&#39;你的输入有误,请输入"yes"or"no":&#39;)
                if panduan == &#39;等待&#39;:
                    panduan_if = []
                    print(&#39;你选择了等待,程序将时刻检测目标位置的颜色以执行接下来的步骤块&#39;)
                    panduan_if.append(&#39;等待&#39;)
                    panduans.append(panduan_if)
                if panduan != &#39;步骤块&#39; and panduan != &#39;如果&#39; and panduan != &#39;等待&#39;:
                    print(&#39;你的输入有误&#39;)
            if len(panduans) > 0:
                print(&#39;你一录入了至少一个逻辑判断,请选择继续选择目标位置的颜色来触发接下来你选择的步骤块&#39;)
                panduan_if = []
                while 1:
                    click_dongzuo = input(&#39;请移动鼠标到目标位置上吸取颜色,输入“1”完成动作,输入“0”取消动作&#39;)
                    if click_dongzuo == &#39;1&#39;:
                        xy = get_xy()
                        click_color = GetColor(xy)
                        panduan_yn = input(f&#39;这个位置的RGB为:{click_color},是否确定为下一步骤块的判断根据?(输入"yes"or"no")\n&#39;)
                        while 1:
                            if panduan_yn == &#39;yes&#39;:
                                get_caozuo_name()
                                print(f&#39;请选择满足当颜色为{click_color}时要执行的步骤包:&#39;)
                                steps, steps_name = daoru()
                                xunhuan_yn = input(&#39;这个步骤块是否循环执行直至条件触发?(输入"yes"or"no")\n&#39;)
                                while 1:
                                    if xunhuan_yn == &#39;yes&#39;:
                                        panduan_if.append(&#39;如果&#39;)
                                        panduan_if.append(xy)
                                        panduan_if.append(click_color)
                                        panduan_if.append(steps_name)
                                        panduan_if.append(&#39;循环&#39;)
                                        panduan_if.append(steps)
                                        panduans.append(panduan_if)
                                        print(&#39;添加成功,该步骤包将会循环&#39;)
                                        break
                                    elif xunhuan_yn == &#39;no&#39;:
                                        panduan_if.append(&#39;如果&#39;)
                                        panduan_if.append(xy)
                                        panduan_if.append(click_color)
                                        panduan_if.append(steps_name)
                                        panduan_if.append(&#39;不循环&#39;)
                                        panduan_if.append(steps)
                                        panduans.append(panduan_if)
                                        print(&#39;添加成功,该步骤包将只执行一次&#39;)
                                        break
                                    else:
                                        xunhuan_yn = input(&#39;你的输入有误,请输入"yes"or"no":&#39;)
                                tuichu = 1
                                break
                            if panduan_yn == &#39;no&#39;:
                                print(&#39;请重新选择&#39;)
                                break
                            else:
                                panduan_yn = input(&#39;你的输入有误,请输入"yes"or"no"&#39;)
                        if tuichu == 1:
                            break
                    elif click_dongzuo == &#39;0&#39;:
                        print(&#39;操作已取消&#39;)
                        break
                    else:
                        print(&#39;请输入正确的操作(输入“0”或“1”)&#39;)
        if choose == &#39;逻辑执行&#39;:
            print(&#39;这里是逻辑执行库,所有的逻辑判断都会存储到这里&#39;)
            print(panduans)
            xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(&#39;等待&#39;, &#39;1&#39;, &#39;循环&#39;))
            xiancheng.setDaemon(True)
            xiancheng.start()
            for pan in panduans:
                state = &#39;未触发&#39;
                if pan[0] == &#39;如果&#39;:
                    print(pan[5])
                    print(len(pan[5]))
                    bu = str(pan[5])
                    print(bu)
                    bu = readListFromStr(bu)
                    zhixing(bu)
                    print(bu)
                    if state == &#39;未触发&#39;:
                        if pan[4] == &#39;循环&#39;:
                            rgb = pan[2]
                            rgb_xy = pan[1]
                            _thread.start_new_thread(jianshi, ())
                            while 1:
                                if state == &#39;触发&#39;:
                                    xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[3], pan[5], &#39;循环&#39;))
                                    xiancheng.start()
                                    state = &#39;未触发&#39;
                                    break
                        if pan[4] == &#39;不循环&#39;:
                            rgb = pan[2]
                            rgb_xy = pan[1]
                            _thread.start_new_thread(jianshi, ())
                            while 1:
                                if state == &#39;触发&#39;:
                                    xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[3], pan[5], &#39;不循环&#39;))
                                    xiancheng.start()
                                    state = &#39;未触发&#39;
                                    break
                if pan[0] == &#39;步骤块&#39;:
                    stop_thread(xiancheng)
                    if pan[1] == &#39;循环&#39;:
                        xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[2], pan[3], &#39;循环&#39;))
                        xiancheng.start()
                    if pan[1] == &#39;不循环&#39;:
                        xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[2], pan[3], &#39;不循环&#39;))
                        xiancheng.start()
                if pan[0] == &#39;等待&#39;:
                    print(&#39;程序正在监测目标位置RGB值&#39;)
            print(&#39;逻辑执行已全部执行完毕&#39;)
            break
        if choose == &#39;逻辑块存储&#39;:
            yorn = input("确定保存?\n输入&#39;yes&#39;or&#39;no&#39;\n")
            while 1:
                if yorn == &#39;yes&#39;:
                    if len(panduans) == 0:
                        print(&#39;还未记录你任何操作,请添加操作再使用逻辑块存储功能&#39;)
                    else:
                        do_name = input(&#39;请为以上操作命名吧:&#39;)
                        if &#39;逻辑块存储&#39; in do_name:
                            do_name = input(&#39;抱歉,你的命名里不允许包含”逻辑块存储“,请重新命名&#39;)
                        else:
                            path = r"{}逻辑块存储.txt".format(do_name)
                            listtotxt(list=panduans, path=path)
                    break
                if yorn == &#39;no&#39;:
                    print(&#39;你已取消存储&#39;)
                    break
                else:
                    yorn = input("请输入&#39;yes&#39;or&#39;no&#39;:\n")
        if choose == &#39;逻辑块导入&#39;:
            caozuojiyi = get_caozuokuai_name()
            while True:
                xunhuan_choose = input(&#39;已存储的操作有:{}\n请输入导入操作的操作名:&#39;.format(caozuojiyi))
                if xunhuan_choose in caozuojiyi:
                    break
                else:
                    print(&#39;逻辑块存储库中并无你想要的操作,请重新输入:&#39;)
            caozuopath = r"{}逻辑块存储.txt".format(xunhuan_choose)
            panduans = txttolist(path=caozuopath)
     
        if choose == 'q' or choose == 'quit' or choose == '退出' or choose == 'close':
            break
        if choose == 'tips' or choose == '提示' or choose == 'help' or choose == '帮助':
            print(
                '''你可以输入'点击', '右击', '中击', '逻辑执行', '判断', '滚动', '延时', '存储', '执行', '循环执行', '拖拽', '连点', '输入', '双击', '查看',
                          '导入', 'q', 'quit','退出', 'close', 'tips', '提示', 'help', '帮助', '按键'来帮助你完成你的自动化操作''')
        if not choose in ['点击', '右击', '中击', '逻辑执行', '判断', '滚动', '延时', '存储', '执行', '循环执行', '拖拽', '连点', '输入', '双击', '查看',
                          '导入', 'q', 'quit','退出', 'close', 'tips', '提示', 'help', '帮助', '按键']:
            print('你的输入有误或暂未开发此功能,请重新输入(输入”help“获得提示)')
    print('代码已全部执行完毕,程序已退出')
    登入後複製

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

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

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

    import pyttsx3
    engine = pyttsx3.init()
    engine.say(&#39;我抢到了!快来看一下&#39;)
    engine.runAndWait()
    登入後複製

    以上是怎麼利用Python實作自訂連點器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    相關標籤:
    來源:yisu.com
    本網站聲明
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
    熱門教學
    更多>
    最新下載
    更多>
    網站特效
    網站源碼
    網站素材
    前端模板