前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >打包py、文件转换、验证码识别、获取文件等问题

打包py、文件转换、验证码识别、获取文件等问题

原创
作者头像
用户6841540
发布2024-07-28 09:03:06
1070
发布2024-07-28 09:03:06
举报
文章被收录于专栏:安义技术分享

pyinstaller——用于打包py程序

在日常中我们写好的pyhton脚本每次运行时都需要安装软件,但是这样造成了一个不好的现象就是,你写好脚本后需要供别人使用的时候,别人没下载软件则无法运行脚本,很麻烦很难受。

所以我们只需要将Python程序打包为exe文件以后,发送给任何人都可以使用,我们打包成exe需要使用到的工具是pyinstaller模块。

首先我们先安装pyinstaller

Python 默认并不包含 PyInstaller 模块,因此需要自行安装 PyInstaller 模块。安装 PyInstaller 模块与安装其他 Python 模块一样,使用 pip 命令安装即可。在命令行输入如下命令:pip install pyinstaller

PyInstaller生成可执行程序

pyinstaller 选项 Python 源文件:pyinstaller -F py文件路径

也可以先在cmd中 cd 进入到文件路径中,然后输入:yinstaller -F 文件名

不管这个 Python 应用是单文件的应用,还是多文件的应用,只要在使用 pyinstaller 命令时编译作为程序入口的 Python 程序即可。

例子:

我们简单创建一个文件:price.py

代码语言:python
代码运行次数:0
复制
import time

def main():
    for i in range(3):
    print(“开始打印第%s次” % i)
    time.sleep(2) # 沉睡两秒后继续执行



if name == ‘main’:
    main()
    print(“执行完毕”)

接下来使用命令行工具进入到此 app 目录下,执行如下命令:

我们先在cmd进入到文件地址,执行pyinstaller -F price.py将看到详细的生成过程。当生成完成后,将会在此 app 目录下看到多了一个 dist 目录,并在该目录下看到有一个 app.exe 文件,这就是使用 PyInstaller 工具生成的 EXE 程序。

打包后,在 pyinstaller 选项 Python 源文件 中,选项处时有很多参数的:

例如(其中部分):

代码语言:bash
复制
-F,-onefile产生单个的可执行文件

-D,–onedir产生一个目录(包含多个文件)作为可执行程序

-a,–ascii不包含 Unicode 字符集支持

-d,–debug产生 debug 版本的可执行文件

但是这样打包以后的exe是原生图标,对于强迫症患者来说是一件很难受的事情,不过我们可以是使用 -i 加上需要显示的图片,这样就能更改打包后exe文件的图片了。pyinstaller -F price.py -i a.ico,但要注意所需设置的图片名格式得为ico后缀的才行

注:使用pyinstaller -F flower.py打包完成的exe文件运行时会弹出黑色的框(命令行窗口),为了使运行exe文件不再出现黑框,加上-w参数,即pyinstaller -F -w flower.py,则运行exe文件时黑框便没有了。

python将csv文件转换为unix的txt文件

目的:将csv文件保存为用空格分隔的且编码方式为utf-8,unix格式的txt文件。相关代码如下:

代码语言:python
代码运行次数:0
复制
# -*- coding:utf-8 -*-
# @author:Ye Zhoubing
# @datetime:2024/7/8 19:31
# @software: PyCharm
import csv
import os
import stat

def convert_csv_to_txt(csv_file, txt_file):
    with open(csv_file, 'r') as file:
        csv_reader = csv.reader(file)
        with open(txt_file, 'w', encoding="utf-8") as output_file:
            for row in csv_reader:
                line = ' '.join(row)  # 使用空格连接每个字段
                output_file.write(line + '\n')  # 写入TXT文件,并在行末添加换行符


def change_dos_to_unix(file):
    subpath = file
    mode = os.stat(subpath)[stat.ST_MODE]
    with open(subpath, "rb+") as file_handle:
        all_text = file_handle.read()
        all_change_text = all_text.replace(b"\r\n", b"\n")
        file_handle.seek(0, 0)
        file_handle.truncate()
        file_handle.write(all_change_text)


# 示例用法
csv_file = 'test.csv'
txt_file = 'output.txt'
convert_csv_to_txt(csv_file, txt_file)

change_dos_to_unix(txt_file)  # txt文件转换为UNIX格式
print("over")

参考链接

ddddocr识别计算型验证码方法

ddddocr是不支持直接识别计算计算型验证码的,比如下面这个。

可以识别后再进行处理。

代码如下:

代码语言:python
代码运行次数:0
复制
# -*- coding:utf-8 -*-
# @author:Ye Zhoubing
# @datetime:2024/7/1 19:16
# @software: PyCharm
# -*- coding: utf-8 -*-
# @Author: b01e
# @Time: 2023/8/9 17:19
# @File: dddd_ikun.py
# @Describe: from ddddocr 修改
# coding=utf-8
"""
注意一下使用版本的pillow
这个工程中使用的是pillow-9.5.0
针对的是:https://www.houdunren.com/login后盾人网站的登录验证码
todo:目前识别有些问题
"""
import ddddocr
import requests
import re


class RegularCalculation:
    __div = re.compile(r"(\d+\.?\d*/-\d+\.?\d*)|(\d+\.?\d*/\d+\.?\d*)")  # 查找除法运算

    __mul = re.compile(r"(\d+\.?\d*\*-\d+\.?\d*)|(\d+\.?\d*\*\d+\.?\d*)")  # 查找乘法运算

    __add = re.compile(r"(-?\d+\.?\d*\+-\d+\.?\d*)|(-?\d+\.?\d*\+\d+\.?\d*)")  # 查找加法运算

    __sub = re.compile(r"(-?\d+\.?\d*--\d+\.?\d*)|(-?\d+\.?\d*-\d+\.?\d*)")  # 查找减法运算

    def division(self, value):
        """计算除法"""
        exp = re.split(r'/', self.__div.search(value).group())  # 将除法表达式拆分成列表
        return value.replace(self.__div.search(value).group(), str(float(exp[0]) / float(exp[1])))  # 计算并用结果替换列表中表达式

    def multiplication(self, value):
        """计算乘法"""
        exp = re.split(r'\*', self.__mul.search(value).group())  # 将乘法表达式拆分成列表
        return value.replace(self.__mul.search(value).group(), str(float(exp[0]) * float(exp[1])))  # 计算并用结果替换列表中表达式

    def addition(self, value):
        """计算加法"""
        exp = re.split(r'\+', self.__add.search(value).group())  # 将加法表达式拆分成列表
        return value.replace(self.__add.search(value).group(), str(float(exp[0]) + float(exp[1])))  # 计算并用结果替换列表中表达式

    def subtraction(self, value):
        """计算减法"""
        exp = self.__sub.search(value).group()  # 去除减法表达式
        if exp.startswith('-'):  # 如果表达式形如:-2.2-1.2;需变换为:-(2.2+1.2)
            exp = exp.replace('-', '+')  # 将-号替换为+号;+2.2+1.2
            res = self.addition(exp).replace('+', '-')  # 调用Add运算,将返回值+3.4变为-3.4
        else:
            exp = re.split(r'-', exp)
            res = str(float(exp[0]) - float(exp[1]))
        return value.replace(self.__sub.search(value).group(), res)


class VerificationCode:

    def __init__(self):
        # 这里将验证码图片保存在本地test.png
        # head = {
        #     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"
        # }
        #
        # res_img = requests.get('https://www.登录地址.com/', headers=head)
        # with open('test.png', 'wb') as f:
        #     f.write(res_img.content)
        pass

    @staticmethod
    def verification_code():
        ocr = ddddocr.DdddOcr(show_ad=False)  # show_ad=False关闭广告
        with open("test.png", 'rb') as f:
            img_bytes = f.read()
        res = ocr.classification(img_bytes)
        # print(res)
        try:
            if '+' in res:
                result = RegularCalculation().addition(res)
            elif '-' in res:
                result = RegularCalculation().subtraction(res)
            elif 'x' in res:  # 因为测试的验证码只有加号,识别出来的乘号是x其实也是+
                # result = RegularCalculation().multiplication(res.replace('x', '*'))
                result = RegularCalculation().addition(res.replace('x', '+'))
            else:
                result = RegularCalculation().division(res)
        except Exception as e:
            result = '计算出错'
            print(e)
        print(result.split('.')[0])


if __name__ == '__main__':
    test = VerificationCode()
    test.verification_code()

注意:

目前有些问题,ddddocr识别该验证码识别率比较低。还有就是+符号稍微偏一点,可能程序就会将其识别为x。目前就是手动将识别成x的转换成+

获取控制台运行的python程序及参数

有时候,需要对运行的程序进行获取(比如多个程序同时进行,但参数与程序名有些区别),要想获取控制台运行的python程序及参数,下面的代码片段便可实现:

代码语言:python
代码运行次数:0
复制
# -*- coding:utf-8 -*-
# @author:Ye Zhoubing
# @datetime:2024/7/2 9:01
# @software: PyCharm
import sys

i = sys.argv[1]

# 获取当前正在执行的Python脚本的名称
script_name = sys.argv[0]

# 获取传递给脚本的参数列表(如果有的话)
arguments = sys.argv[1]

print(f"程序: {script_name} {arguments},已完成")

文件拖拽进窗口获取文件路径

下面介绍两种包下的实现方式:pyQt5与tkinter

pyQt5

相关代码如下:

代码语言:python
代码运行次数:0
复制
# -*- coding:utf-8 -*-
# @author:Ye Zhoubing
# @datetime:2024/6/30 15:55
# @software: PyCharm
"""
拖拽文件进入窗口获取文件路径

"""
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit, QPushButton, QVBoxLayout, QWidget, QDesktopWidget

'''
#1、使用以下代码中的文件拖拽功能,只需将文件或文件夹拖拽到文本编辑框中即可。如果文件是本地文件,它们将以文件路径的形式显示在文本编辑框中。
#2、如果你想要进一步处理这些文件路径,比如复制、移动、读取或执行其他操作,你可以在 processFiles 方法中添加你的自定义代码,该方法在用户点击提交按钮后被调用。在该方法中,你可以访问文本编辑框的内容,将其拆分成文件路径,并执行相应的操作。
'''


# 使用子类来继承父类的方法,这里的’DragDropTextEdit‘,继承自  ’QTextEdit‘ ,并且添加了文件拖拽的支持。
# 这使得你可以将它用作拖拽文件的目标,以便在应用程序中方便地处理文件路径。
class DragDropTextEdit(QTextEdit):
    def __init__(self, parent=None):
        super(DragDropTextEdit, self).__init__(parent)
        self.setAcceptDrops(True)  # 定义的 DragDropTextEdit 类的构造函数中调用的方法,它的作用是启用该文本编辑框接受拖拽操作。

    # 当用户拖拽文件或其他可拖拽的内容进入文本编辑框时,这个方法会被触发
    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():  # 它检查拖拽事件中的 MIME 数据是否包含文件路径
            event.accept()  # 如果包含文件路径,它调用 event.accept() 来接受拖拽事件,允许文件拖拽进入文本编辑框。
        else:  # 否则,如果不包含文件路径,它调用 event.ignore() 来忽略拖拽事件,表示不允许拖拽操作。
            event.ignore()

    def dropEvent(self, event):  # 当用户释放鼠标按钮时,这个方法会被触发,用于处理拖拽事件。在这个方法中,你可以获取拖拽事件中的文件路径。
        for url in event.mimeData().urls():  # 使用 event.mimeData().urls() 来获取所有拖拽事件中的 URL 列表,每个 URL 表示一个文件或文件夹。
            if url.isLocalFile() and url.toLocalFile():  # 使用 url.toLocalFile() 来获取本地文件路径,如果是本地文件的话。
                self.append(url.toLocalFile())  # 接下来,你可以将这些文件路径添加到文本编辑框中,或者进行任何你希望执行的处理。


class MainApp(QMainWindow):  # 创建实例化类
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('文件拖拽窗口')  # 设置主窗口的标题为 "文件拖拽窗口"。
        # 获取屏幕的宽度和高度
        screen = QDesktopWidget().screenGeometry()
        screenWidth = screen.width()
        screenHeight = screen.height()
        # 计算窗口居中的坐标
        x = (screenWidth - self.width()) // 2
        y = (screenHeight - self.height()) // 2
        # 设置窗口大小已经出现在屏幕的什么位置
        self.setGeometry(x, y, 600, 400)  # 设置主窗口的初始位置和大小。 (x, y)是设置窗口出现的位置。窗口的宽度为 600 像素,高度为 400 像素。

        # 初始化窗口排版模式
        central = QWidget(self)  # 创建一个名为 central 的 QWidget(窗口中央部件),用于将其他小部件添加到主窗口的中央区域。
        self.setCentralWidget(central)  # 将 central 部件设置为主窗口的中央部分。这意味着所有其他小部件将放置在 central 部件中,以确保它们在窗口中间显示。
        display = QVBoxLayout(central)  # 创建一个垂直布局管理器 display,它将用于管理 central 部件中的小部件的位置和大小。垂直布局意味着小部件将按垂直方向排列。

        # 窗口
        self.textEdit = DragDropTextEdit()  #####这里来实例化上面子类继承的内容DragDropTextEdit 的实例,并将其赋值给 self.textEdit 属性。这个文本编辑框支持文件拖拽功能。
        display.addWidget(self.textEdit)  # 将 self.textEdit 添加到垂直布局管理器 display 中
        # 按钮
        self.submit_Button = QPushButton('提交文件', self)  # 创建提交按钮的名称
        self.submit_Button.clicked.connect(self.processFiles)  # 给提交按钮绑定事件函数processFiles
        display.addWidget(self.submit_Button)  # 展示出提交按钮

    def processFiles(self):
        file_paths = self.textEdit.toPlainText().split('\n')
        # 这里添加处理文件的代码
        print("文件路径如下:", file_paths)


def main():
    app = QApplication(sys.argv)
    ex = MainApp()
    ex.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

界面如下:

Tkinter

注:Tkinter本身是不支持拖拽文件进入它的窗口的,所以需要借助pip install tkinterdnd2 这个包,然后from tkinterdnd2 import * 这样就可以使用拖拽文件到窗口功能了

相关代码如下:

代码语言:python
代码运行次数:0
复制
# -*- coding:utf-8 -*-
# @author:Ye Zhoubing
# @datetime:2024/6/30 14:15
# @software: PyCharm
"""
拖拽获取文件路径
todo:目前无法将文件拖入窗口,待解决
"""
import tkinter as tk
from tkinter import messagebox
from tkinterdnd2 import DND_FILES, TkinterDnD

root = TkinterDnD.Tk()

#获取拖拽的文件名称
def on_drop(event):
    file_path = event.data
    file_label.config(text="拖拽的文件: " + file_path)

#设置窗口标题
root.title("文件拖拽")
#设置窗口大小
root.geometry("300x300")

#设置拖拽功能
file_label = tk.Label(root, text="请把文件拖拽到这里:")
file_label.pack(pady=20)

# 允许文件拖入
root.drop_target_register(DND_FILES)


root.dnd_bind('<<Drop>>', on_drop)

root.mainloop()

参考链接

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • pyinstaller——用于打包py程序
    • 首先我们先安装pyinstaller
      • PyInstaller生成可执行程序
        • 例子:
        • python将csv文件转换为unix的txt文件
          • ddddocr识别计算型验证码方法
            • 注意:
        • 获取控制台运行的python程序及参数
        • 文件拖拽进窗口获取文件路径
          • pyQt5
            • Tkinter
            相关产品与服务
            AI 应用产品
            文字识别(Optical Character Recognition,OCR)基于腾讯优图实验室的深度学习技术,将图片上的文字内容,智能识别成为可编辑的文本。OCR 支持身份证、名片等卡证类和票据类的印刷体识别,也支持运单等手写体识别,支持提供定制化服务,可以有效地代替人工录入信息。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档