pyinstaller+selenium 编译windows exe小记
基于pyinstaller生成exe文件
安装库:pip install pyinstaller
1. pyinstaller是什么?
介绍
PyInstaller 将 Python 应用程序及其所有依赖项捆绑到单个软件包中。用户无需安装 Python 解释器或任何模块,即可运行打包后的应用程序。PyInstaller 支持 Python 3.8 及其更新版本,并能正确捆绑 numpy、matplotlib、PyQt、wxPython 等许多主流 Python 包。
PyInstaller 已经过 Windows、MacOS X 和 Linux 测试。不过,**它并不是一个交叉编译器**;要制作 Windows 应用程序就需要在 Windows 上运行 PyInstaller,要制作 Linux 应用程序就需要在 Linux 上运行它,依此类推。PyInstaller 已成功在 AIX、Solaris、FreeBSD、OpenBSD 上使用,但针对这些平台的测试未纳入官方的持续集成测试,所以不能保证(这些平台的所有代码都来自外部贡献)PyInstaller将能够在这些平台上运行,或得到持续支持。
用处
+ 主要用于将python文件打包成exe文件,摆脱python软件对本地python环境以及部分python库的依赖,实现在其他机器上低成本的安装和运行。
+ 其次还可以将项目依赖的资源一起打包,避免特殊平台下缺少dll或者部分库无法运行的情况。
优点
+ 打包命令比较简单
+ 支持生成单文件程序
+ 支持生成产物单文件夹-dist
缺点
+ 对于python库依赖的第三方组件(如:selenium依赖与chromdriver.exe)需手动将文件加入datas集合中,否则exe中无法找到第三方组件会报错;
2. pyinstaller基础
命令
+ -Fw : 用于生成单个程序文件的命令,会对资源文件和代码文件进行适当压缩,有代码被反编译的风险(思路:可以使用工具将代码转为机器代码)
+ --add-data target-file:dest-dir (有代码被反编译的风险)
+ 释义:
+ target-file: 要打包的目标文件路径或者目标文件集所在目录,可以是基于当前打包目录的相对路径,也可以是绝对路径,如**src/libconv.dll**或者**assets**
+ dest-dir: 目标文件要打包到的目录名,以 **pyinstaller test.py** 为例,执行并生成dist后,在**dist/test**目录下就包含所有的dest-dir文件夹,dest-dir如果写成"."的话相当于**dist/test/**目录,若写成"assets"的话则相当于**dist/test/assets/**.
Spec配置文件
+ 介绍:一般在执行pyinstaller test.py后,会在当前目录生成test.spec文件,该文件包含打包相关的参数,也可以基于test.spec文件进行打包,如 pyinstaller test.spec.
+ 示例:
a = Analysis(['test.py'],
pathex=['/Developer/PItests/minimal'],
binaries=None,
datas=[('src/libconv.dll','.'),('ca.key','seleniumwire'),('ca.crt','seleniumwire'),('assets','assets')],
hiddenimports=[],
hookspath=None,
runtime_hooks=None,
excludes=None)
pyz = PYZ(a.pure)
exe = EXE(pyz,... )
coll = COLLECT(...)
打包用法
+ 无第三方文件打包
pyinstaller target.py
+ 带第三方文件打包
+ 典型场景示例
+ 场景一 第三方文件依赖:若python项目引入了selenium包,则必然涉及到对chromedriver.exe、chrome.exe的使用,假设不将这些第三方exe文件打包到程序内部,则若将程序分发到其他未安装chrome的机器上运行,必然会出现错误;
+ 场景二 库文件依赖:若项目中引入了pyzbar库,则打包出来的exe文件在运行时会报错"xxx.dll not found"类似的错误,这主要是在打包时未将dll引入所导致的。
+ 打包示例
+ 方法1-命令参数法
+ 命令:
pyinstaller --add-data ca.crt;seleniumwire --add-data ca.key;seleniumwire --add-data chrome;chrome target.py
+ 方法2-修改.spec文件法
+ 操作: 将spec文件中的data参数修改为: datas=[('ca.key','seleniumwire'),('ca.crt','seleniumwire'),('chrome','chrome')],
程序执行
+ 拷贝生成的dist下对应的目录,比如test
+ 双击或者在命令行下执行test目录下的test程序