首頁 > 軟體

利用Python實現自定義連點器

2022-08-21 14:00:12

前言

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

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

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)

實現思路大致流程圖:

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

整體思路

一般需要的功能有:點選、延時、連點、拖拽。一般這四個功能就能完成絕大多數的簡單的輔助指令碼開發了,但我想做得稍微高階一點,功能多一點,就想另外開發:迴圈、判斷、模擬按鍵、文字輸入、儲存操作、讀取操作的功能。

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

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

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

每一個列表的第0項就是需要操作的功能,第0項之後都是各種引數。

所有功能

簡單演示

點選功能

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

也可以參考:如何利用Python獲取滑鼠的實時位置

定義獲取位置函數

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] == '[':
            # 將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_caozuo_name():
    files1 = []
    file_dir = r"C:UsersgeDesktoptest1我的作品自定義連點器"
    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 == '迴圈執行':
    caozuojiyi = get_caozuo_name()
    while True:
        xunhuan_choose = input('已儲存的操作有:{}n請輸入迴圈操作的操作名:'.format(caozuojiyi))
        if xunhuan_choose in caozuojiyi:
            break
        else:
            print('儲存庫中並無你想要的操作,請重新輸入:')

儲存匯入功能【升級版】

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

匯入(功能實現)

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

匯入(邏輯程式碼)

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

    if choose == '匯入':
        if len(step) == 0:
            step = daoru()[0]
        else:
            baocun_choose = input('此次操作若未儲存請先,匯入別的操作會覆蓋原來的操作,你確定要匯入嗎?n請輸入「yes」or「no」:n')
            while 1:
                if baocun_choose == 'no':
                    break
                if baocun_choose == 'yes':
                    print('你已取消儲存')
                    step = daoru()[0]
                    break
                else:
                    yorn = input("請輸入'yes'or'no':n")

儲存(功能實現)

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 listtotxt(list, path):
    import json
    c_list = list
    c_list = json.dumps(c_list)
    '''將c_list存入檔案
    '''
    a = open(path, "w", encoding='UTF-8')
    a.write(c_list)
    a.close()
    print('已存入txt')

儲存(邏輯程式碼) 

要是程式記憶體裡還沒有操作將提醒

    if choose == '儲存':
        if len(step) == 0:
            print('還未記錄你任何操作,請新增操作再使用儲存功能')
        else:
            do_name = input('請為以上操作命名吧:')
            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='left')
print(f'已執行拖拽動作,拖拽起始位置是X:{int(i[1][0])},Y:{int(i[1][1])},拖拽後的位置是X:{int(i[2][0])},Y:{int(i[2][1])}')

邏輯程式碼:

先建立列表tuozhuai,向列表新增三個引數:“拖拽”、第一個位置引數、第二個位置引數

    if choose == '拖拽':
        tuozhuai = []
        while 1:
            click_dongzuo = input('請移動滑鼠到目標位置上輸入「1」完成移動前的位置輸入,輸入「0」取消動作')
            if click_dongzuo == '1':
                click_weizhi = get_xy()
                tuozhuai.append('拖拽')
                tuozhuai.append(click_weizhi)
                while 1:
                    click_dongzuo = input('請移動滑鼠到目標位置上輸入「1」完成移動後的位置輸入,輸入「0」取消動作')
                    if click_dongzuo == '1':
                        click_weizhi = get_xy()
                        tuozhuai.append(click_weizhi)
                        break
                    elif click_dongzuo == '0':
                        print('操作已取消')
                        break
                    else:
                        print('請輸入正確的操作(輸入「0」或「1」')
                break
            elif click_dongzuo == '0':
                print('操作已取消')
                break
            else:
                print('請輸入正確的操作(輸入「0」或「1」')
        step.append(tuozhuai)

也是用到了pyauogui庫,主要使用pyautogui庫的pytewrite函數,但是這個函數對中文不友好,於是我另闢蹊徑使用pyperclip庫的copy函數將要輸入的文字內容拷貝打貼上板,通過控制按鍵control+v來輸入至目標位置。

功能實現

    if choose == '輸入':
        shuru = []
        while 1:
            click_dongzuo = input('請移動滑鼠到你要輸入的位置上輸入「1」完成動作,輸入「0」取消動作')
            if click_dongzuo == '1':
                click_weizhi = get_xy()
                txt_in = input('請輸入你要在該位置輸入的文字:n')
                shuru.append('輸入')
                shuru.append(click_weizhi)
                shuru.append(txt_in)
                step.append(shuru)
                break
            elif click_dongzuo == '0':
                print('操作已取消')
                break
            else:
                print('請輸入正確的操作(輸入「0」或「1」')

 邏輯程式碼

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

右擊、中擊、雙擊功能的實現

原理相同,將不再贅述

功能實現

        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] == '右擊':
            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 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」')
        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 i[0] == '按鍵':
            pyautogui.hotkey(*i[1])

邏輯程式碼

    if choose == '按鍵':
        while 1:
            anjian = input('這是模擬操作鍵盤的操作(例如複製,輸入'ctrl‘ + 'c‘):n')
            if anjian != 'q':
                anjian = anjian.split('+')
                anjians = []
                a = []
                for an in anjian:
                    an = an.replace("‘", "").replace("'", "").strip()
                    if an in pyautogui.KEYBOARD_KEYS:
                        anjians.append(an)
                        nihaofan = 0
                    else:
                        print('你的輸入不合法')
                        nihaofan = 1
                        break
                if nihaofan == 0:
                    a.append('按鍵')
                    a.append(anjians)
                    step.append(a)
                    print('錄入成功')
                    break
 
            if anjian == 'q':
                break

捲動滾輪功能

功能實現

        if i[0] == '捲動':
            import pywinauto.mouse
            x, y = pyautogui.position()
            pywinauto.mouse.scroll((x, y), i[1])  # (1100,300)是初始座標,1000是滑動距離(可負)

邏輯程式碼

    if choose == '捲動':
        while 1:
            gundong = []
            try:
                gundong1 = int(input('這裡是模擬滑鼠捲動,請輸入你要捲動距離(正數為向上移動,負數為向下移動):n'))
                gundong.append('捲動')
                gundong.append(gundong1)
                step.append(gundong)
                break
            except:
                print('你的輸入有誤,請重新輸入')

檢視功能

def chakan():
    if len(step) == 0:
        print('暫未錄入操作,請先錄入操作再檢視')
    zizeng = 1
    for i in step:
        if i[0] == '點選':
            x = int(i[1][0])
            y = int(i[1][1])
            print(f'第{zizeng}步:n執行點選動作,點選座標位置:X:{x},Y:{y}   ')
        if i[0] == '延時':
            t = int(i[1])
            print(f'第{zizeng}步:n執行延時動作,延時時長:{t}秒')
        if i[0] == '連點':
            if i[2] == '連點次數':
                print(f'第{zizeng}步:n執行連點操作,你選擇的是{i[2]},連點次數是{i[4]}')
            if i[2] == '連點時長':
                print(f'第{zizeng}步:n執行連點操作,你選擇的是{i[2]},連點時長是{i[4]}秒')
        if i[0] == '拖拽':
            print(
                f'第{zizeng}步:n執行拖拽動作,拖拽起始位置是X:{int(i[1][0])},Y:{int(i[1][1])},拖拽後的位置是X:{int(i[2][0])},Y:{int(i[2][1])}')
        if i[0] == '雙擊':
            print(f'第{zizeng}步:n執行點選動作,點選座標位置:X:{int(i[1][0])},Y:{int(i[1][1])}   ')
 
        if i[0] == '按鍵':
            print(f'第{zizeng}步:n執行按鍵動作,將同時按下」{i[1]}「鍵')
        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] == '輸入':
            pyautogui.click(int(i[1][0]), int(i[1][1]))
            pyperclip.copy(i[2])
            time.sleep(0.1)
            pyautogui.hotkey('ctrl', 'v')
        if i[0] == '按鍵':
            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] == '捲動':
            import pywinauto.mouse
            x, y = pyautogui.position()
            pywinauto.mouse.scroll((x, y), i[1])  # (1100,300)是初始座標,1000是滑動距離(可負)
    if choose == '執行':
        if len(step) == 0:
            print('你還未記錄任何操作,請至少記錄了一個操作再執行')
        else:
            zhixing(step)
            cunchu()

邏輯判斷功能板塊

到了最難最虐腦的邏輯判斷功能了,邏輯判斷板塊這幾個功能困擾了我一整天,敲到我腦殼疼

判斷功能

實現這一功能主要是基於顏色的RBG值來判斷程式所要要執行的步驟塊。

選擇目標點,開啟執行緒去時刻監管這個目標點的顏色變化,一旦目標顏色變為期待值,立即執行之前儲存的步驟塊,可以選擇是否迴圈這個步驟塊的操作。選擇完畢後開啟第二個執行緒去執行這個步驟塊,此時主程式將繼續遍歷panduans的操作。設定一個while迴圈來阻塞主程式的執行及監控state變數值的變化,state初始值為“未觸發”,一旦監管執行緒發現目標值變化為期待值,立即修改state值為“觸發”,同時關閉執行步驟塊的執行緒,同時關閉自身的監管執行緒,此時主程式檢測到state值為“觸發”後立刻將新的步驟塊的執行緒開啟並將state值修改為“未觸發”。就此開啟新一輪的迴圈。

之間呢,遇到了多個執行緒修改同一個值的情況導致報錯;遇到了多種停止執行緒的方法都不適用的情況;遇到了沒設定守護行程又要找到這個程序去關閉的情況;嘗試了老版的_thread程序庫、嘗試了主流的threading程序庫、嘗試了執行緒池的方法,終於找到一條適合我的方法。不容易呀

判斷功能的邏輯程式碼

    if choose == '判斷':
        if len(panduans) == 0:
            tuichu = 0
            panduan = input('此功能的實現是基於顏色的RBG值來判斷程式所要要執行的步驟塊。n現在,請選擇你的‘先執行步驟塊等待條件觸發'或是‘直接等待條件觸發'的操作:(輸入"步驟塊"或"等待")n')
            if panduan == '如果':
                panduan_if = []
                while 1:
                    click_dongzuo = input('請移動滑鼠到目標位置上吸取顏色,輸入「1」完成動作,輸入「0」取消動作')
                    if click_dongzuo == '1':
                        xy = get_xy()
                        click_color = GetColor(xy)
                        panduan_yn = input(f'這個位置的RGB為:{click_color},是否確定為下一步驟塊的判斷根據?(輸入"yes"or"no")n')
                        while 1:
                            if panduan_yn == 'yes':
                                get_caozuo_name()
                                print(f'請選擇滿足當顏色為{click_color}時要執行的步驟包:')
                                steps, steps_name = daoru()
                                xunhuan_yn = input('這個步驟塊是否迴圈執行至下一條件觸發?(輸入"yes"or"no")n')
                                while 1:
                                    if xunhuan_yn == 'yes':
                                        panduan_if.append('如果')
                                        panduan_if.append(xy)
                                        panduan_if.append(click_color)
                                        panduan_if.append(steps_name)
                                        panduan_if.append('迴圈')
                                        panduan_if.append(steps)
                                        panduans.append(panduan_if)
                                        print('新增成功,該步驟包將會迴圈')
                                        break
                                    elif xunhuan_yn == 'no':
                                        panduan_if.append('如果')
                                        panduan_if.append(xy)
                                        panduan_if.append(click_color)
                                        panduan_if.append(steps_name)
                                        panduan_if.append('不迴圈')
                                        panduan_if.append(steps)
                                        panduans.append(panduan_if)
                                        print('新增成功,該步驟包將只執行一次')
                                        break
                                    else:
                                        xunhuan_yn = input('你的輸入有誤,請輸入"yes"or"no":')
                                tuichu = 1
                                break
                            if panduan_yn == 'no':
                                print('請重新選擇')
                                break
                            else:
                                panduan_yn = input('你的輸入有誤,請輸入"yes"or"no"')
                        if tuichu == 1:
                            break
                    elif click_dongzuo == '0':
                        print('操作已取消')
                        break
                    else:
                        print('請輸入正確的操作(輸入「0」或「1」)')
            if panduan == '步驟塊':
                panduan_step = []
                steps, steps_name = daoru()
                xunhuan_yn = input('這個步驟塊是否迴圈執行直至條件觸發?(輸入"yes"or"no")n')
                while 1:
                    if xunhuan_yn == 'yes':
                        panduan_step.append('步驟塊')
                        panduan_step.append('迴圈')
                        panduan_step.append(steps_name)
                        panduan_step.append(steps)
                        panduans.append(panduan_step)
                        break
                    elif xunhuan_yn == 'no':
                        panduan_step.append('步驟塊')
                        panduan_step.append('不迴圈')
                        panduan_step.append(steps_name)
                        panduan_step.append(steps)
                        panduans.append(panduan_step)
                        break
                    else:
                        xunhuan_yn = input('你的輸入有誤,請輸入"yes"or"no":')
            if panduan == '等待':
                panduan_if = []
                print('你選擇了等待,程式將時刻檢測目標位置的顏色以執行接下來的步驟塊')
                panduan_if.append('等待')
                panduans.append(panduan_if)
            if panduan != '步驟塊' and panduan != '如果' and panduan != '等待':
                print('你的輸入有誤')
        if len(panduans) > 0:
            print('你一錄入了至少一個邏輯判斷,請選擇繼續選擇目標位置的顏色來觸發接下來你選擇的步驟塊')
            panduan_if = []
            while 1:
                click_dongzuo = input('請移動滑鼠到目標位置上吸取顏色,輸入「1」完成動作,輸入「0」取消動作')
                if click_dongzuo == '1':
                    xy = get_xy()
                    click_color = GetColor(xy)
                    panduan_yn = input(f'這個位置的RGB為:{click_color},是否確定為下一步驟塊的判斷根據?(輸入"yes"or"no")n')
                    while 1:
                        if panduan_yn == 'yes':
                            get_caozuo_name()
                            print(f'請選擇滿足當顏色為{click_color}時要執行的步驟包:')
                            steps, steps_name = daoru()
                            xunhuan_yn = input('這個步驟塊是否迴圈執行直至條件觸發?(輸入"yes"or"no")n')
                            while 1:
                                if xunhuan_yn == 'yes':
                                    panduan_if.append('如果')
                                    panduan_if.append(xy)
                                    panduan_if.append(click_color)
                                    panduan_if.append(steps_name)
                                    panduan_if.append('迴圈')
                                    panduan_if.append(steps)
                                    panduans.append(panduan_if)
                                    print('新增成功,該步驟包將會迴圈')
                                    break
                                elif xunhuan_yn == 'no':
                                    panduan_if.append('如果')
                                    panduan_if.append(xy)
                                    panduan_if.append(click_color)
                                    panduan_if.append(steps_name)
                                    panduan_if.append('不迴圈')
                                    panduan_if.append(steps)
                                    panduans.append(panduan_if)
                                    print('新增成功,該步驟包將只執行一次')
                                    break
                                else:
                                    xunhuan_yn = input('你的輸入有誤,請輸入"yes"or"no":')
                            tuichu = 1
                            break
                        if panduan_yn == 'no':
                            print('請重新選擇')
                            break
                        else:
                            panduan_yn = input('你的輸入有誤,請輸入"yes"or"no"')
                    if tuichu == 1:
                        break
                elif click_dongzuo == '0':
                    print('操作已取消')
                    break
                else:
                    print('請輸入正確的操作(輸入「0」或「1」)')

邏輯執行功能的實現

    if choose == '邏輯執行':
        print('這裡是邏輯執行庫,所有的邏輯判斷都會儲存到這裡')
        print(panduans)
        xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=('等待', '1', '迴圈'))
        xiancheng.setDaemon(True)
        xiancheng.start()
        for pan in panduans:
            state = '未觸發'
            if pan[0] == '如果':
                print(pan[5])
                print(len(pan[5]))
                bu = str(pan[5])
                print(bu)
                bu = readListFromStr(bu)
                zhixing(bu)
                print(bu)
                if state == '未觸發':
                    if pan[4] == '迴圈':
                        rgb = pan[2]
                        rgb_xy = pan[1]
                        _thread.start_new_thread(jianshi, ())
                        while 1:
                            if state == '觸發':
                                xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[3], pan[5], '迴圈'))
                                xiancheng.start()
                                state = '未觸發'
                                break
                    if pan[4] == '不迴圈':
                        rgb = pan[2]
                        rgb_xy = pan[1]
                        _thread.start_new_thread(jianshi, ())
                        while 1:
                            if state == '觸發':
                                xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[3], pan[5], '不迴圈'))
                                xiancheng.start()
                                state = '未觸發'
                                break
            if pan[0] == '步驟塊':
                stop_thread(xiancheng)
                if pan[1] == '迴圈':
                    xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[2], pan[3], '迴圈'))
                    xiancheng.start()
                if pan[1] == '不迴圈':
                    xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[2], pan[3], '不迴圈'))
                    xiancheng.start()
            if pan[0] == '等待':
                print('程式正在監測目標位置RGB值')
        print('邏輯執行已全部執行完畢')
        break

邏輯塊儲存功能的實現

def listtotxt(list, path):
    import json
    c_list = list
    c_list = json.dumps(c_list)
    '''將c_list存入檔案
    '''
    a = open(path, "w", encoding='UTF-8')
    a.write(c_list)
    a.close()
    print('已存入txt')

邏輯塊儲存邏輯程式碼

    if choose == '邏輯塊儲存':
        yorn = input("確定儲存?n輸入'yes'or'no'n")
        while 1:
            if yorn == 'yes':
                if len(panduans) == 0:
                    print('還未記錄你任何操作,請新增操作再使用邏輯塊儲存功能')
                else:
                    do_name = input('請為以上操作命名吧:')
                    if '邏輯塊儲存' in do_name:
                        do_name = input('抱歉,你的命名裡不允許包含」邏輯塊儲存「,請重新命名')
                    else:
                        path = r"{}邏輯塊儲存.txt".format(do_name)
                        listtotxt(list=panduans, path=path)
                break
            if yorn == 'no':
                print('你已取消儲存')
                break
            else:
                yorn = input("請輸入'yes'or'no':n")

邏輯塊匯入功能的實現

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

邏輯塊匯入邏輯程式碼

    if choose == '邏輯塊匯入':
        caozuojiyi = get_caozuokuai_name()
        while True:
            xunhuan_choose = input('已儲存的操作有:{}n請輸入匯入操作的操作名:'.format(caozuojiyi))
            if xunhuan_choose in caozuojiyi:
                break
            else:
                print('邏輯塊儲存庫中並無你想要的操作,請重新輸入:')
        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] == '輸入':
            pyautogui.click(int(i[1][0]), int(i[1][1]))
            pyperclip.copy(i[2])
            time.sleep(0.1)
            pyautogui.hotkey('ctrl', 'v')
        if i[0] == '按鍵':
            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] == '捲動':
            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('暫未錄入操作,請先錄入操作再檢視')
    zizeng = 1
    for i in step:
        if i[0] == '點選':
            x = int(i[1][0])
            y = int(i[1][1])
            print(f'第{zizeng}步:n執行點選動作,點選座標位置:X:{x},Y:{y}   ')
        if i[0] == '延時':
            t = int(i[1])
            print(f'第{zizeng}步:n執行延時動作,延時時長:{t}秒')
        if i[0] == '連點':
            if i[2] == '連點次數':
                print(f'第{zizeng}步:n執行連點操作,你選擇的是{i[2]},連點次數是{i[4]}')
            if i[2] == '連點時長':
                print(f'第{zizeng}步:n執行連點操作,你選擇的是{i[2]},連點時長是{i[4]}秒')
        if i[0] == '拖拽':
            print(
                f'第{zizeng}步:n執行拖拽動作,拖拽起始位置是X:{int(i[1][0])},Y:{int(i[1][1])},拖拽後的位置是X:{int(i[2][0])},Y:{int(i[2][1])}')
        if i[0] == '雙擊':
            print(f'第{zizeng}步:n執行點選動作,點選座標位置:X:{int(i[1][0])},Y:{int(i[1][1])}   ')
 
        if i[0] == '按鍵':
            print(f'第{zizeng}步:n執行按鍵動作,將同時按下」{i[1]}「鍵')
        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)
    '''將c_list存入檔案
    '''
    a = open(path, "w", encoding='UTF-8')
    a.write(c_list)
    a.close()
    print('已存入txt')
 
 
def txttolist(path):
    import json
    b = open(path, "r", encoding='UTF-8')
    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 == '儲存':
        if len(step) == 0:
            print('還未記錄你任何操作,請新增操作再使用儲存功能')
        else:
            do_name = input('請為以上操作命名吧:')
            path = r"{}.txt".format(do_name)
            listtotxt(list=step, path=path)
    if choose == '拖拽':
        tuozhuai = []
        while 1:
            click_dongzuo = input('請移動滑鼠到目標位置上輸入「1」完成移動前的位置輸入,輸入「0」取消動作')
            if click_dongzuo == '1':
                click_weizhi = get_xy()
                tuozhuai.append('拖拽')
                tuozhuai.append(click_weizhi)
                while 1:
                    click_dongzuo = input('請移動滑鼠到目標位置上輸入「1」完成移動後的位置輸入,輸入「0」取消動作')
                    if click_dongzuo == '1':
                        click_weizhi = get_xy()
                        tuozhuai.append(click_weizhi)
                        break
                    elif click_dongzuo == '0':
                        print('操作已取消')
                        break
                    else:
                        print('請輸入正確的操作(輸入「0」或「1」')
                break
            elif click_dongzuo == '0':
                print('操作已取消')
                break
            else:
                print('請輸入正確的操作(輸入「0」或「1」')
        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 == '匯入':
        if len(step) == 0:
            step = daoru()[0]
        else:
            baocun_choose = input('此次操作若未儲存請先,匯入別的操作會覆蓋原來的操作,你確定要匯入嗎?n請輸入「yes」or「no」:n')
            while 1:
                if baocun_choose == 'no':
                    break
                if baocun_choose == 'yes':
                    print('你已取消儲存')
                    step = daoru()[0]
                    break
                else:
                    yorn = input("請輸入'yes'or'no':n")
    if choose == '輸入':
        shuru = []
        while 1:
            click_dongzuo = input('請移動滑鼠到你要輸入的位置上輸入「1」完成動作,輸入「0」取消動作')
            if click_dongzuo == '1':
                click_weizhi = get_xy()
                txt_in = input('請輸入你要在該位置輸入的文字:n')
                shuru.append('輸入')
                shuru.append(click_weizhi)
                shuru.append(txt_in)
                step.append(shuru)
                break
            elif click_dongzuo == '0':
                print('操作已取消')
                break
            else:
                print('請輸入正確的操作(輸入「0」或「1」')
    if choose == '按鍵':
        while 1:
            anjian = input('這是模擬操作鍵盤的操作(例如複製,輸入'ctrl‘ + 'c‘):n')
            if anjian != 'q':
                anjian = anjian.split('+')
                anjians = []
                a = []
                for an in anjian:
                    an = an.replace("‘", "").replace("'", "").strip()
                    if an in pyautogui.KEYBOARD_KEYS:
                        anjians.append(an)
                        nihaofan = 0
                    else:
                        print('你的輸入不合法')
                        nihaofan = 1
                        break
                if nihaofan == 0:
                    a.append('按鍵')
                    a.append(anjians)
                    step.append(a)
                    print('錄入成功')
                    break
 
            if anjian == 'q':
                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 == '捲動':
        while 1:
            gundong = []
            try:
                gundong1 = int(input('這裡是模擬滑鼠捲動,請輸入你要捲動距離(正數為向上移動,負數為向下移動):n'))
                gundong.append('捲動')
                gundong.append(gundong1)
                step.append(gundong)
                break
            except:
                print('你的輸入有誤,請重新輸入')
    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 == '執行':
        if len(step) == 0:
            print('你還未記錄任何操作,請至少記錄了一個操作再執行')
        else:
            zhixing(step)
            cunchu()
    if choose == '判斷':
        if len(panduans) == 0:
            tuichu = 0
            panduan = input('此功能的實現是基於顏色的RBG值來判斷程式所要要執行的步驟塊。n現在,請選擇你的‘先執行步驟塊等待條件觸發'或是‘直接等待條件觸發'的操作:(輸入"步驟塊"或"等待")n')
            if panduan == '如果':
                panduan_if = []
                while 1:
                    click_dongzuo = input('請移動滑鼠到目標位置上吸取顏色,輸入「1」完成動作,輸入「0」取消動作')
                    if click_dongzuo == '1':
                        xy = get_xy()
                        click_color = GetColor(xy)
                        panduan_yn = input(f'這個位置的RGB為:{click_color},是否確定為下一步驟塊的判斷根據?(輸入"yes"or"no")n')
                        while 1:
                            if panduan_yn == 'yes':
                                get_caozuo_name()
                                print(f'請選擇滿足當顏色為{click_color}時要執行的步驟包:')
                                steps, steps_name = daoru()
                                xunhuan_yn = input('這個步驟塊是否迴圈執行至下一條件觸發?(輸入"yes"or"no")n')
                                while 1:
                                    if xunhuan_yn == 'yes':
                                        panduan_if.append('如果')
                                        panduan_if.append(xy)
                                        panduan_if.append(click_color)
                                        panduan_if.append(steps_name)
                                        panduan_if.append('迴圈')
                                        panduan_if.append(steps)
                                        panduans.append(panduan_if)
                                        print('新增成功,該步驟包將會迴圈')
                                        break
                                    elif xunhuan_yn == 'no':
                                        panduan_if.append('如果')
                                        panduan_if.append(xy)
                                        panduan_if.append(click_color)
                                        panduan_if.append(steps_name)
                                        panduan_if.append('不迴圈')
                                        panduan_if.append(steps)
                                        panduans.append(panduan_if)
                                        print('新增成功,該步驟包將只執行一次')
                                        break
                                    else:
                                        xunhuan_yn = input('你的輸入有誤,請輸入"yes"or"no":')
                                tuichu = 1
                                break
                            if panduan_yn == 'no':
                                print('請重新選擇')
                                break
                            else:
                                panduan_yn = input('你的輸入有誤,請輸入"yes"or"no"')
                        if tuichu == 1:
                            break
                    elif click_dongzuo == '0':
                        print('操作已取消')
                        break
                    else:
                        print('請輸入正確的操作(輸入「0」或「1」)')
            if panduan == '步驟塊':
                panduan_step = []
                steps, steps_name = daoru()
                xunhuan_yn = input('這個步驟塊是否迴圈執行直至條件觸發?(輸入"yes"or"no")n')
                while 1:
                    if xunhuan_yn == 'yes':
                        panduan_step.append('步驟塊')
                        panduan_step.append('迴圈')
                        panduan_step.append(steps_name)
                        panduan_step.append(steps)
                        panduans.append(panduan_step)
                        break
                    elif xunhuan_yn == 'no':
                        panduan_step.append('步驟塊')
                        panduan_step.append('不迴圈')
                        panduan_step.append(steps_name)
                        panduan_step.append(steps)
                        panduans.append(panduan_step)
                        break
                    else:
                        xunhuan_yn = input('你的輸入有誤,請輸入"yes"or"no":')
            if panduan == '等待':
                panduan_if = []
                print('你選擇了等待,程式將時刻檢測目標位置的顏色以執行接下來的步驟塊')
                panduan_if.append('等待')
                panduans.append(panduan_if)
            if panduan != '步驟塊' and panduan != '如果' and panduan != '等待':
                print('你的輸入有誤')
        if len(panduans) > 0:
            print('你一錄入了至少一個邏輯判斷,請選擇繼續選擇目標位置的顏色來觸發接下來你選擇的步驟塊')
            panduan_if = []
            while 1:
                click_dongzuo = input('請移動滑鼠到目標位置上吸取顏色,輸入「1」完成動作,輸入「0」取消動作')
                if click_dongzuo == '1':
                    xy = get_xy()
                    click_color = GetColor(xy)
                    panduan_yn = input(f'這個位置的RGB為:{click_color},是否確定為下一步驟塊的判斷根據?(輸入"yes"or"no")n')
                    while 1:
                        if panduan_yn == 'yes':
                            get_caozuo_name()
                            print(f'請選擇滿足當顏色為{click_color}時要執行的步驟包:')
                            steps, steps_name = daoru()
                            xunhuan_yn = input('這個步驟塊是否迴圈執行直至條件觸發?(輸入"yes"or"no")n')
                            while 1:
                                if xunhuan_yn == 'yes':
                                    panduan_if.append('如果')
                                    panduan_if.append(xy)
                                    panduan_if.append(click_color)
                                    panduan_if.append(steps_name)
                                    panduan_if.append('迴圈')
                                    panduan_if.append(steps)
                                    panduans.append(panduan_if)
                                    print('新增成功,該步驟包將會迴圈')
                                    break
                                elif xunhuan_yn == 'no':
                                    panduan_if.append('如果')
                                    panduan_if.append(xy)
                                    panduan_if.append(click_color)
                                    panduan_if.append(steps_name)
                                    panduan_if.append('不迴圈')
                                    panduan_if.append(steps)
                                    panduans.append(panduan_if)
                                    print('新增成功,該步驟包將只執行一次')
                                    break
                                else:
                                    xunhuan_yn = input('你的輸入有誤,請輸入"yes"or"no":')
                            tuichu = 1
                            break
                        if panduan_yn == 'no':
                            print('請重新選擇')
                            break
                        else:
                            panduan_yn = input('你的輸入有誤,請輸入"yes"or"no"')
                    if tuichu == 1:
                        break
                elif click_dongzuo == '0':
                    print('操作已取消')
                    break
                else:
                    print('請輸入正確的操作(輸入「0」或「1」)')
    if choose == '邏輯執行':
        print('這裡是邏輯執行庫,所有的邏輯判斷都會儲存到這裡')
        print(panduans)
        xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=('等待', '1', '迴圈'))
        xiancheng.setDaemon(True)
        xiancheng.start()
        for pan in panduans:
            state = '未觸發'
            if pan[0] == '如果':
                print(pan[5])
                print(len(pan[5]))
                bu = str(pan[5])
                print(bu)
                bu = readListFromStr(bu)
                zhixing(bu)
                print(bu)
                if state == '未觸發':
                    if pan[4] == '迴圈':
                        rgb = pan[2]
                        rgb_xy = pan[1]
                        _thread.start_new_thread(jianshi, ())
                        while 1:
                            if state == '觸發':
                                xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[3], pan[5], '迴圈'))
                                xiancheng.start()
                                state = '未觸發'
                                break
                    if pan[4] == '不迴圈':
                        rgb = pan[2]
                        rgb_xy = pan[1]
                        _thread.start_new_thread(jianshi, ())
                        while 1:
                            if state == '觸發':
                                xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[3], pan[5], '不迴圈'))
                                xiancheng.start()
                                state = '未觸發'
                                break
            if pan[0] == '步驟塊':
                stop_thread(xiancheng)
                if pan[1] == '迴圈':
                    xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[2], pan[3], '迴圈'))
                    xiancheng.start()
                if pan[1] == '不迴圈':
                    xiancheng = threading.Thread(target=zhixingbuzhoukuai, args=(pan[2], pan[3], '不迴圈'))
                    xiancheng.start()
            if pan[0] == '等待':
                print('程式正在監測目標位置RGB值')
        print('邏輯執行已全部執行完畢')
        break
    if choose == '邏輯塊儲存':
        yorn = input("確定儲存?n輸入'yes'or'no'n")
        while 1:
            if yorn == 'yes':
                if len(panduans) == 0:
                    print('還未記錄你任何操作,請新增操作再使用邏輯塊儲存功能')
                else:
                    do_name = input('請為以上操作命名吧:')
                    if '邏輯塊儲存' in do_name:
                        do_name = input('抱歉,你的命名裡不允許包含」邏輯塊儲存「,請重新命名')
                    else:
                        path = r"{}邏輯塊儲存.txt".format(do_name)
                        listtotxt(list=panduans, path=path)
                break
            if yorn == 'no':
                print('你已取消儲存')
                break
            else:
                yorn = input("請輸入'yes'or'no':n")
    if choose == '邏輯塊匯入':
        caozuojiyi = get_caozuokuai_name()
        while True:
            xunhuan_choose = input('已儲存的操作有:{}n請輸入匯入操作的操作名:'.format(caozuojiyi))
            if xunhuan_choose in caozuojiyi:
                break
            else:
                print('邏輯塊儲存庫中並無你想要的操作,請重新輸入:')
        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('我搶到了!快來看一下')
engine.runAndWait()

當然暫時還沒有這些需求,如果我哪天有空就再更新到3.0版本哈,你們感興趣的可以自己新增功能,至少我語音功能的邏輯程式碼已經給你們了。真不是懶【偷笑】

以上就是利用Python實現自定義連點器的詳細內容,更多關於Python連點器的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com