自动化exe程序

python生成的EXE如何自动退出 python自动化exe_ui


简单介绍一下,这个exe原本是为闲鱼发布内容点击增加浏览量量身定做的。

应用程序路径:指的是你要打开的exe程序,例如夜神

图片文件路径:指的是自动化程序,要根据那个文件夹下的内容去执行,文件中png中图片的命令格式为:数字_*.png
数字表示执行序号,1就是第一个被执行的图片,紧接着下划线不能少,然后随意,最后就是一个png

解析:就是会分析你文件夹中的内容

图片执行顺序:就是解析之后,要按照以下顺序去执行

重复执行其中的步骤:就是难免有些步骤是需要重复的,前提是重复的步骤,不如4-10,那么在10执行完成之后必须货到3界面才能连接上4,否则不成立

重复执行次数:默认一直重复,否则按照指定的选项重复

开始执行:执行设定好的程序

执行日志会被保存到指定目录下。

——————————————————————————

当然程序怎么运行,完全取决于你的配置。
——————————————————————————

请看视频效果

python | 第4集 自动化程序,完成自定义配置的运行。

以下是运行日志截图

# -*- coding: utf-8 -*-
import datetime
import os
import re
import sys
import threading
import time
from threading import Thread

import lackey
import psutil as psutil
import pywinauto
from PyQt5 import QtCore
from PyQt5.QtCore import QStringListModel
from PyQt5.QtWidgets import QMessageBox, QAbstractItemView, QTextEdit, QLabel, QPushButton, QListView, QRadioButton, \
    QMainWindow, QApplication


# Form implementation generated from reading ui file 'untitled.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


class Ui_Dialog(object):
    def __init__(self):

        # self.txt_repeat = None
        self.png_name_show = None
        self.label = None
        self.btn_start_exe = None
        self.txt_png_exe_order = None
        self.txt_repeat_step = None
        self.input_repeat_step = None
        self.listView_exe_order = None
        self.btn_analysis = None
        self.input_png_path = None
        self.txt_png_path = None
        self.exe_path = None
        self.input_exe_path = None
        self.radioButton_1 = None
        self.radioButton_10 = None
        self.radioButton_50 = None
        self.radioButton_100 = None
        self.model = None
        self.file = None
        # 创建日志文件
        # 检查C盘是否存在python_log文件夹

        if os.path.isdir(r'C:/python_log') is False:
            # 创建日志文件目录
            os.mkdir(r'C:/python_log')
        self.write_log(info='***************************************************')
        self.write_log(info='欢迎使用自动化程序,我是陈子清,请多多指教
        self.write_log(info='***************************************************')
        self.write_log(info='[1]成员变量初始化完成')

    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(1026, 568)
        self.input_exe_path = QTextEdit(Dialog)
        self.input_exe_path.setGeometry(QtCore.QRect(140, 30, 811, 31))
        self.input_exe_path.setObjectName("input_exe_path")
        self.exe_path = QLabel(Dialog)
        self.exe_path.setGeometry(QtCore.QRect(50, 30, 91, 31))
        self.exe_path.setObjectName("exe_path")
        self.txt_png_path = QLabel(Dialog)
        self.txt_png_path.setGeometry(QtCore.QRect(50, 90, 91, 31))
        self.txt_png_path.setObjectName("txt_png_path")
        self.input_png_path = QTextEdit(Dialog)
        self.input_png_path.setGeometry(QtCore.QRect(140, 90, 811, 31))
        self.input_png_path.setObjectName("input_png_path")
        self.btn_analysis = QPushButton(Dialog)
        self.btn_analysis.setGeometry(QtCore.QRect(50, 140, 71, 31))
        self.btn_analysis.setObjectName("btn_analysis")
        self.listView_exe_order = QListView(Dialog)
        self.listView_exe_order.setGeometry(QtCore.QRect(140, 190, 811, 192))
        self.txt_png_exe_order = QLabel(Dialog)
        self.txt_png_exe_order.setGeometry(QtCore.QRect(50, 190, 91, 31))
        self.txt_png_exe_order.setObjectName("txt_png_exe_order")

        # 重复步骤
        self.txt_repeat_step = QLabel(Dialog)
        self.txt_repeat_step.setGeometry(QtCore.QRect(50, 400, 500, 31))
        self.txt_repeat_step.setObjectName("txt_repeat_step")
        # 输入重复步骤
        self.input_repeat_step = QTextEdit(Dialog)
        self.input_repeat_step.setGeometry(QtCore.QRect(300, 400, 200, 31))
        self.input_repeat_step.setObjectName("input_repeat_step")

        # self.txt_repeat = QLabel(Dialog)
        # self.txt_repeat.setGeometry(QtCore.QRect(50, 400, 91
        self.listView_exe_order.setObjectName("listView_exe_order")
        self.radioButton_1 = QRadioButton(Dialog)
        self.radioButton_1.setGeometry(QtCore.QRect(80, 440, 89, 16))
        self.radioButton_1.setObjectName("radioButton")
        self.radioButton_10 = QRadioButton(Dialog)
        self.radioButton_10.setGeometry(QtCore.QRect(210, 440, 89, 16))
        self.radioButton_10.setObjectName("radioButton_2")
        self.radioButton_50 = QRadioButton(Dialog)
        self.radioButton_50.setGeometry(QtCore.QRect(350, 440, 89, 16))
        self.radioButton_50.setObjectName("radioButton_3")
        self.radioButton_100 = QRadioButton(Dialog)
        self.radioButton_100.setGeometry(QtCore.QRect(490, 440, 101, 16))
        self.radioButton_100.setObjectName("radioButton_4")
        self.btn_start_exe = QPushButton(Dialog)
        self.btn_start_exe.setGeometry(QtCore.QRect(50, 490, 71, 31))
        self.btn_start_exe.setObjectName("btn_analysis_2")
        self.label = QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(140, 490, 600, 31))
        self.label.setObjectName("label")

        self.retranslateUi(Dialog)
        self.click_event()
        QtCore.QMetaObject.connectSlotsByName(Dialog)

        self.write_log(info='[2]视图渲染和事件初始化完成')

    def click_event(self):
        # 解析按钮的点击事件
        self.btn_analysis.clicked.connect(self.btn_analysis_event)

        # 图片执行顺序的点击事件
        self.listView_exe_order.doubleClicked.connect(self.qlistView_doubleClick_event)

        # 开始执行的点击事件
        self.btn_start_exe.clicked.connect(self.btn_start_exe_event)

    def btn_analysis_event(self):
        self.write_log(info='触发解析事件')
        # 1_wangzheringyao.PNG
        png_path = self.input_png_path.toPlainText()
        # 判断当前文件目录是不是存在
        flag = os.path.exists(png_path)
        if not flag:
            self.write_log(info='当前文件目录不存在,请检查!')
            msg_box = QMessageBox(QMessageBox.Information, '提示信息', '当前文件目录不存在,请检查!')
            msg_box.exec_()
            return
        # 如果存在那么需要获取下面的文件名
        png_name_list = os.listdir(png_path)
        self.png_name_show = list()
        num = 1
        for item in png_name_list:
            # 当前文件名不是数字开头的就踢出去
            m = re.match('^[0-9]*_', item)
            if m is not None and item.endswith('.png'):
                self.png_name_show.append("第" + str(num) + "步:" + item)
                num += 1
        self.model = QStringListModel()
        # 文件名升序排列
        list.sort(self.png_name_show, reverse=False)
        self.model.setStringList(self.png_name_show)

        #
        self.listView_exe_order.setModel(self.model)
        self.listView_exe_order.setEditTriggers(QAbstractItemView.NoEditTriggers)

    def qlistView_doubleClick_event(self, qModelIndex):
        """
        图片执行顺序的点击事件
        :param qModelIndex:
        :return:
        """
        from PIL import Image
        img_path = self.input_png_path.toPlainText() + '\\' + self.png_name_show[qModelIndex.row()]
        im = Image.open(img_path)
        im.show()
        self.write_log(info='打开图片' + self.png_name_show[qModelIndex.row()] + '!')

    def btn_start_exe_event(self):

        """
        开始执行的点击事件
        :return:
        """
        self.write_log(info='触发开始执行事件!')
        # 获取执行次数
        print(self.radioButton_1.isChecked())
        print(self.radioButton_10.isChecked())
        print(self.radioButton_50.isChecked())
        print(self.radioButton_100.isChecked())
        if self.radioButton_1.isChecked():
            exe_count = 1
        elif self.radioButton_10.isChecked():
            exe_count = 10
        elif self.radioButton_50.isChecked():
            exe_count = 50
        elif self.radioButton_100.isChecked():
            exe_count = 100
        else:
            exe_count = 100000
        self.write_log(info='当前程序执行' + str(exe_count) + '次!')
        # 自动化执行函数
        self.auto_exe(exe_count)

        print("程序执行完毕!")

    def auto_exe(self, exe_count):
        # while exe_count > 0:
        # 打开应用程序
        pywinauto.Application(backend='win32').start(cmd_line=self.input_exe_path.toPlainText())
        exe_info = ''
        # 记录执行日志
        start_step = str(self.input_repeat_step.toPlainText()).split(',')[0]
        end_step = str(self.input_repeat_step.toPlainText()).split(',')[1].split(" ")[0]
        print(str(start_step) + str(end_step))
        print(exe_count)
        repeat_list = list()
        is_start_record = False
        for pns in self.png_name_show:
            print(pns)
            print("第" + start_step + "步")
            print("第" + end_step + "步")
            if "第" + start_step + "步" in pns:
                is_start_record = True
            if is_start_record:
                repeat_list.append(pns)
            if "第" + end_step + "步" in pns:
                is_start_record = False
            pns = str(pns).split(":")[1]
            self.try_lock_and_click(png_path=self.input_png_path.toPlainText() + '\\' + pns, message=pns, button='left')
            print(str(is_start_record) + str(len(repeat_list)) + str(exe_count))
            if is_start_record is False and len(repeat_list) > 0 and exe_count > 0:
                list.sort(repeat_list, reverse=False)
                while exe_count > 0:
                    print("start to repeated work !")
                    for repeat_step in repeat_list:
                        repeat_step = str(repeat_step).split(":")[1]
                        print(repeat_step)
                        self.try_lock_and_click(self.input_png_path.toPlainText() + '\\' + repeat_step, message=pns,
                                                button='left')
                    self.write_log(info='第' + str(exe_count) + '次,执行完毕!')
                    exe_count -= 1
                print("end repeated work !")
        # 关闭进程
        # for process in psutil.process_iter():
        #     try:
        #         cmdline = process.cmdline()
        #         try:
        #             if len(cmdline):
        #                 if self.input_exe_path.toPlainText() in cmdline[0]:
        #                     process.terminate()
        #         except Exception as e:
        #             self.write_log(info='发生异常' + e.args[0] + '!')
        #     except Exception as e:
        #         self.write_log(info='发生异常' + e.args[0] + '!')

    # 尝试锁定并点击 Try locking and clicking
    def try_lock_and_click(self, png_path='', message='', button='left'):
        time_out = 120
        while time_out > 0:
            try:
                screen = lackey.Screen()
                match = screen.findBest(pattern=lackey.Pattern(png_path))
                if button in 'left':
                    screen.click(match)
                if button in 'right':
                    screen.rightClick(match)
                self.write_log(info='锁定[' + message + ']成功!')
                time.sleep(2)
                return True
            except Exception as e:
                self.write_log(info='锁定[' + message + ']失败!')
            time.sleep(1)
            time_out -= 1
            if time_out == 0:
                self.write_log(info='锁定超时,退出锁定(程序终止)...')
                exit(0)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.input_exe_path.setHtml(_translate("Dialog",
                                               "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
                                               "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
                                               "p, li { white-space: pre-wrap; }\n"
                                               "</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
                                               "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">D:\\Program Files\\Nox\\bin\\Nox.exe</p></body></html>"))
        self.exe_path.setText(_translate("Dialog", "应用程序路径"))
        self.txt_png_path.setText(_translate("Dialog", "图片文件路径"))
        self.input_png_path.setHtml(_translate("Dialog",
                                               "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
                                               "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
                                               "p, li { white-space: pre-wrap; }\n"
                                               "</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
                                               "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">C:\\Users\\Administrator\\Desktop\\test\\xianyu</p></body></html>"))
        self.btn_analysis.setText(_translate("Dialog", "解析"))
        self.txt_png_exe_order.setText(_translate("Dialog", "图片执行顺序"))
        self.txt_repeat_step.setText(_translate("Dialog", "重复执行其中的步骤(逗号隔开,例如:4,5))"))
        self.input_repeat_step.setHtml(_translate("Dialog",
                                                  "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
                                                  "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
                                                  "p, li { white-space: pre-wrap; }\n"
                                                  "</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
                                                  "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">4,5 表示第4步到第5步</p></body></html>"))

        self.radioButton_1.setText(_translate("Dialog", "只执行1次"))
        self.radioButton_10.setText(_translate("Dialog", "重复执行10次"))
        self.radioButton_50.setText(_translate("Dialog", "重复执行50次"))
        self.radioButton_100.setText(_translate("Dialog", "重复执行100次"))
        self.btn_start_exe.setText(_translate("Dialog", "开始执行"))
        self.label.setText(
            _translate("Dialog", "执行日志将会保存在C:/python_log/log.log文件目录下,点击[执行按钮]后请勿操作屏幕!"))

    def write_log(self, info=''):
        self.file = open(r'C:/python_log/log.log', 'a')
        self.file.write(str(datetime.datetime.now()) + '              ' + info + '\n')
        print(info)
        self.file.close()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    MainWindow = QMainWindow()
    ui = Ui_Dialog()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())