Python 學習 – 用 Pyinstaller 打包成執行檔

最近接了一個案子,案主的需求是簡單的網路爬蟲,需要從網頁上抓些資料,處理之後再供給 Excel 透過 VBA 顯示、處理。一開始,我是用 Windows 10 上的 BASH Shell Script 驗証概念,確定可以後再移到 Python 上。

Python 寫好後為了達成方便使用,就去看怎麼把 Python 打包成執行檔,不然程式拿到其它機器都要先裝 Python 也太麻煩。由於還利用到了一個 Tidy 的 HTML 美化 Library,算是一個比較完整的打包需求,就寫篇文章把這個流程記下來。

Python 版本

這篇文章是利用 Python 2.7.15 x86寫的,在 Python3 下面則沒有驗証過。 Python 2.7.15 在安裝時都已經考慮的的蠻周全了,環境變數、PIP 都已經一併安裝設定好。裝過早期的 2.7.0,這些都還要手動安裝,因此建議可以直接用 2.7.15 後的,以保証流程會跟我相同。

另外, 也建議安裝 x86 版本。我們稍後會用 3rd party 的預先編譯 Pytidylib, 其不需要 VC10/VC14 的 Runtime library,這對於打包直接使用的 .exe 檔是蠻方便的,因為不需要再另裝 VC Runtime Library。若是使用官方的 Tidy Library, 則有這個要求。但3rd party的檔案只提供 x86版本的,若裝x64版本,則此 library 就無法使用。

安裝

將執行檔加入PATH

Python 安裝,基本上就是一直下一步就好了。稍微要注意一點的,就是安裝時要將 python.exe 加入 PATH 內,以便在命令視窗就可執行。

安裝 Pyinstaller 與原理

要將 python 的程式打包成單一的Windows執行檔,用的正是 Pyinstaller 這個套件。

它的原理是偵測 python 腳本所用到的所有套件,並將它們搜集後連同 python.exe 打包起來,轉換成一個執行檔。在執行這個檔案時,會先將檔案解壓縮到暫存區,再執行它們。以此方法,就可達成將python程式封裝成單一檔案。

安裝 pyinstaller 則是利用簡單的套件安裝命令 pip install pyinstaller 就可以完成。

Python 程式打包成執行檔

一切裝好後,我們以一個最簡單的 ‘Hello World!’ 程式為例子,將之打包成執行檔。

打包的命令

這樣就會生成一個 hello.exe 在 dist/hello.exe 了。

加入 Pytidylib

在客戶的應用裡需要用到 Tidy。Tidy 是一個將 HTML 美化的函式庫,它分成兩個部份,Python 套件與一個 Windows DLL。一般開發時,將 DLL  與 Python 腳本放同一目錄,或放在 C:\Windows\System32內。而在打包成執行檔時,亦要將其加入打包的檔案內。

安裝 pytidylib

PyTidyLib 的官方網頁有提到相關的資訊,pytidylib 需搭配 HTML Tidy,其僅是一個對 DLL 的介面。 pytidylib 可直接使用 pip 安裝。

HTML Tidy 的 DLL 可在其官方網頁下載頁下載,將其解壓縮後,取得 bin/tidy.dll。將其複制一份到 C:\Windows\System32 與 python 腳本下。這樣在執行與打包時,皆可方便使用。官方的DLL檔是用 Visual C++編譯的,因此會要求另外安裝 Runtime Library,這個在打包.exe時會造成不方便,需要要求使用者也安裝 Runtime Library。也許也可以試著將用到的 VC Library 打包進去,但我們這邊使用的方法是用 3rd party 的單一 DLL 檔案。

網路有找到一家公司,有提供預先編好獨立的 Tidy Library,不需要再安裝其它 Library。本文是選用這個方案,文末也會附上,以免將來 Link 遺失。

使用 PyTidyLib

下面是一個最簡單的 Pytidylib 範例,直接將一個文字的 HTML 美化。實用上可搭配 Web 下載套件,下載後再美化輸出。

上面的檔案,執行後會輸出格式化後的 HTML,畫面如圖。

Tidy 輸出結果

Pyinstaller + Tidy Library 打包

若要將使用 DLL 的 Python 程式打包成執行檔,則要將 DLL 也加入檔案內。我們使用 Pyinstaller 的參數 “–add-binary” 來將之加入。因此,完整的打包命令是

pyinstaller -F –add-binary libtidy.dll;. tidy_ex.py

add-binary 命令後面接的參數,是指定將(目前目錄下)libtidy.dll加到執行檔內的根目錄,而中間是用分號(;)隔開。程式的 HELP 有提到也可以用冒號(:)分開,但實用是不行,這點要注意。

被防毒軟體判定為病毒

Pyinstaller (或其它 Python to EXE) 打包出來的程式,有時會被判定為病毒,這跟你程式中使用的 Library 也有相關性。為了避免這個問題,可以考慮用自然人憑証簽署程式,以獲得防毒軟體的信任。

結語

將 Python 檔案打包成單一執行檔,實際上就成了所謂的綠色軟體,使用前不需再裝其它程式。但在交附程式時,其實並不是很喜歡交附執行檔,怕中毒害了人家,資料損毀搞不好還有賠償責任。因此這方面也是需要注意的。另外這邊 Pyinstaller 的測試也是簡單的示範,若有多檔案、多 add-binary的需求,也要請使用者自行嚐試了。

 

附件

3rd Party 的單一DLL x86 Tidy Library

Leave a Reply