SteveHawk's Blog

Python打包输出为.exe可执行文件



  在完成了之前的爬虫以后,为了给电脑上没有Python环境的朋友玩我的爬虫,开始尝试把爬虫的.py文件输出成.exe可执行文件。

  首先,Python的教程上提到了py2exe的模块。但是一波搜索以后发现这个玩意只支持到Python3.4,而我用的是Python3.5.2,这让我很尴尬……于是继续一波搜索,发现了一个叫PyInstaller的模块。这个模块可以完美支持Python3.5,于是怒入。

  首先是安装。下载地址为:https://github.com/pyinstaller/pyinstaller/releases/download/v3.2/PyInstaller-3.2.zip

  如果有更新的版本可以在官方网站上下载:http://www.pyinstaller.org/

  下载完以后,解压这个zip文件。然后用管理员权限运行命令提示符(在小娜里输入 cmd,上面搜索结果里的命令提示符右击以管理员权限运行),进入你解压出来的文件夹路径。(操作方法:进入别的盘符输 x:,例如 d: ; 然后 cd x:.…. 你的目录,例如 cd D:\MyPrograms\python\,不懂可以自行百度)。然后输入以下指令:

1python setup.py install

  然后等待一会,应该就可以完成安装。检验是否安装成功可以使用以下语句:

1pyinstaller --version

  如果有一个版本号的回应,说明安装成功了。如果没有反应,说明没有安装成功,看一下报错信息,很有可能是一个东西没有安装:pywin32模块。

  先尝试在管理员权限的命令提示符里输入:

1pip install pywin32

  如果报错就再试几次。如果还是不行,那就用手动下载离线包的安装方法:

  打开以下网页:https://sourceforge.net/projects/pywin32/files/pywin32/

  然后在列表里选择最新的(数字最大的)build。点开目录,在目录下寻找适合自己的安装包。以build 220为例,文件夹下有一个zip和一片exe。在exe文件中,都是以pywin32-220开头,这是版本号。后面有两种,win-amd64和win32,分别对应64位和32位的版本,可以根据系统的不同位数选择,如果不清楚,选择win32的即可。然后后面会跟着py*.*,这是Python的版本号,我们现在用的一般都是Python3.5.2,所以选择py3.5的那个,即 pywin32-220.win-amd64-py3.5.exe 或者 pywin32-220.win32-py3.5.exe(这两个链接是下载传送门)。如果有使用不同python版本的请自行进入网站对号入座下载安装包。

  下载完以后,直接双击运行。一般就是无脑next即可。

  安装完pywin32以后,再次重复之前的安装操作,应该就可以解决问题了。

  然而根据后来帮舍友安装的经历来看,如果还是有报错,那有可能还有一个模块没有安装:future

  用线下安装包的方法太烦,于是直接打开管理员权限的命令提示符,键入以下指令:

1pip install future

  如果下到一半出错,多半是下载时候连接超时,因为是国外网站,所以可以多试几次,有条件的搭个梯子。

  安装完成以后再重复pyinstaller的安装操作,应该就可以了。

  以上操作是来自官方文档和网上别人的各种博客和后来的部分实践,理论上应该可以,可是我当时没有看官方文档于是语句有问题,没有成功实现以上操作。大家可以先试试,如果不行麻烦告知我。于是(懒惰的)机智的我走了另一条捷径。

  到这里我才发现Windows下也可以像Linux一样很方便的用命令行安装程序。如果你的电脑已经安装好Python,有pip的话,就可以打开cmd(管理员权限),然后键入以下指令:

1pip install PyInstaller

  然而,如果是国内网,可以无视这一条方法了。必报错。请在翻墙以后执行这条指令。如果有权限的报错,请务必用管理员权限运行cmd。

  然后就可以非常非常爽快的安装完这个模块了,而且会自动帮你装pywin32模块以及future模块(如果没有的话),安装完甚至会提示你的pip可以更新了(如果版本太老的话)…..简直太良心了好嘛…..唯一的缺点就是不搭梯子没法用。

  至于翻墙、搭梯子是什么,请自行谷歌(手动斜眼)。

  安装完以后,就可以用这个模块愉快的把你的py编译成exe给小伙伴装逼啦!!hhhhh

  然而还没这么简单。编译有两种方法:命令行方式和直接Python文件调用方法。

命令行方式

  在命令行下进入你的py文件所在目录(操作方法和之前一样)

  然后输入以下指令:(***.py为你要编译的文件名)

1pyinstaller ***.py

  然后等待编译完,在该目录下会新生成四个东西,一个***.spec文件(***和你的py文件同名),一个__pycache__文件夹,一个dist文件夹和一个build文件夹。你要的exe就在dist文件夹里。但是,拷给小伙伴的时候记得把整个文件夹都拷给他们,这一整个文件夹都是exe的一部分。(其他的都是编译过程中的中间文件,输出完就可以删掉了)

  你一定想,这么多东西真是麻烦啊,怎么只输出一个exe呢?那就要加一个单文件的参数-F,如下:

  (其实可用的参数还有不少,在法二中介绍)

1pyinstaller -F ***.py

  然后你就会愉快的发现这时候dist下只有一个exe啦哈哈哈可以愉快的装逼啦wwwww

  でも!!还有更方便的方法!

直接Python文件调用方法

  在Python中直接调用这个模块,会比cmd更方便,至少我是这么认为的。至少,以后再要输出只要把这个文件复制一波,改一两个参数就可以了,简直爽啊。

方法如下:

  首先,在要编译的***.py同目录下创建一个py文件:TargetPy2exe.py(当然其他随便xjb一个名字都可以)

  然后,在其中写入以下代码:

1from PyInstaller.__main__ import run
2if __name__ == '__main__':
3    opts = ['***.py','-F',r'--distpath=**',r'--workpath=**',r'--specpath=**',r'--icon=**']
4    run(opts)

  调整完参数运行就可以输出exe了。

  代码中,opts= 后面的列表里的就是一系列参数,详解如下:

  第一个***.py就是你要编译的文件名,必填 [之后的参数全部为选填]

  第二个-F就是生成单文件的参数

  第三个–distpath=**意思是dist文件夹(最后输出文件所在地)的路径,**为路径,比如D:\My Programs\Python\输出\dist,默认为当前目录下的dist文件夹内

  第四个–workpath=**意思是build文件夹(临时文件)的路径,**为路径,比如D:\My Programs\Python\输出\build,默认为当前目录下的build文件夹内

  第五个–specpath=**意思是***.spec文件(临时文件)的路径,**为路径,比如**D:\My Programs\Python\输出\,**默认为当前目录

  第六个–icon=**意思是输出的exe文件的图标路径,**为路径,比如D:\My Programs\Python\icon.ico

  对于图标,最好到一个叫png2ico的网站上在线生成你所需的ico图标文件,注意,直接把一个jpg图片文件改后缀成.ico会报错 [我一开始就是刷小聪明在这上面耗了好久才发现问题的….(捂脸)]。在png2ico上转换图片的时候,大小记得点auto,这样生成的ico文件会内置四种大小的图标以供系统缩放的需求。

  后面四个参数里的路径也可以不用像我一样用绝对路径,可以使用简单的相对路径。例如你想生成dist,build,spec的目标路径是TargetPy2exe.py所在文件夹里的一个文件夹output,你的三个路径就可以输成相对路径.\output\dist 和 .output\build 和 .output\ ,当然三个未必在同一个文件夹里,仅供示例。

  注意,我在后四个参数的引号前面都加上了r,这是因为不加r会出现各种问题,例如反斜杠导致的转义字符捣乱,以及有些中文目录名里的中文会变成16进制的utf-8码来显示导致路径错误。在这些字符串前加上r(raw)以表示原始字符串就能解决这些问题了。

  其实,pyinstaller能用的参数还不止这几个,还有能添加搜索路径的参数(我也不太懂这个是啥),以及一个–clean参数说是可以清除临时文件,然而我测试的时候发现貌似并没有什么luan用…….附上官方文档地址,英语大神可以尝试阅读。

https://pyinstaller.readthedocs.io/en/stable/

32 & 64位的问题

  另外,关于输出exe文件的32位和64位的问题。这个问题的起因是我的电脑上安装了64位的Python环境,然后用pyinstaller输出的exe文件就是64位的了。然而小伙伴的电脑是32位的,于是妥妥的没法运行了。这就让我很尴尬了…..没法好好装逼了不是…于是怎么输出32位的exe呢?其实很简单,你的Python环境是32位的,输出的exe就会是32位的,64位的就会输出64位的。如果你想既输出32位的,又输出64位的,以下是方法:

  首先分别安装32位和64位的Python环境,并分别安装pyinstaller。切记,安装完一个环境就要立马用pip install pyinstaller安装pyinstaller。如果已经装完了两个环境再安装pyinstaller,会有一个环境安装成功,但是再次运行会提示已经安装,另一个环境会无法成功安装。成功给两个环境装好pyinstaller了以后,如果用cmd命令行的方式调用会出现问题,至少我的电脑上会有这个问题。目前我还不清楚怎么在cmd下分别调用两个环境。这时候Python文件调用的方法就会方便很多。以我使用的pycharm为例,显然要编译的***.py和TargetPy2exe.py是在同一个工程下的。这时,在File选项卡下,打开Setting选项,在Setting窗口左侧栏中找到Project:***(***为工程名)选项,点击左侧灰色三角打开下拉菜单,里面点击Project Interpreter选项,然后在右侧窗口里上面的下拉菜单里选择所需的32位或者64位解释器。选好以后点击下面的OK即可。第一次可能需要等待一会才能运行。然后运行TargetPy2exe.py就可以生成你要的32/64位的exe啦!!

  不过这只是对于我这种强迫症类型的人适用的方法。如果嫌烦,只需要装一个32位的Python环境就可以了,因为64位系统下可以兼容32位的程序…..这是最简单的解决办法。

以上。


#tech notes
本文总字数 4147
本文阅读量
本站访客量

↪ reply by email