Python項目打包指南:PyInstaller與SeleniumWire的兼容性挑戰及解決方案

前言

前段時間做一個內網開發的需求,要求將selenium程序打包成.exe放在內網的win7上運行,在掘金搜了一圈也沒有發現相關文章,因此將過程中踩到的坑記錄分享一下。

本文涵蓋了具體打包操作、不同模塊和依賴項的兼容性解決方案,以確保在打包和運行時都能正常工作。


1. 背景

在 Python 項目中,使用第三方庫(如 seleniumselenium-wiremitmproxy 等)時,會遇到許多依賴項,并且由于庫之間的版本兼容性問題,可能導致運行時錯誤。常用的打包工具 PyInstaller 能將 Python 項目打包成單個可執行文件,但也會因為兼容性問題和路徑管理而出現各種運行錯誤。因此,本指南總結了打包過程中常見問題和解決方案,以幫助開發者順利完成項目的打包和發布。

2. 可能遇到的問題概述

PyInstaller打包selenium-wire時可能會遇到一些問題,如下:

  1. 依賴沖突:如 pyOpenSSLcryptography 的版本沖突問題。
  2. 路徑問題:如 chromedriver.exe 在運行時未找到或未正確加載。
  3. 打包文件缺失:某些文件(如 .crt.keychromedriver.exe 等)在打包時未包含,導致運行時無法找到。

3. PyInstaller 打包步驟及參數配置

使用 PyInstaller 打包一個 Python 項目時,可以通過以下步驟和命令來生成可執行文件:

pyinstaller --onefile --clean --hidden-import=<module> --name=<executable_name> <script.py>

參數詳解:

  • --onefile:將所有文件打包成一個獨立可執行文件。
  • --clean:清理之前打包時的緩存,確保使用最新的依賴版本。
  • --hidden-import:指定打包時包含的隱藏模塊(PyInstaller 有時無法自動檢測到的依賴)。
  • --name:指定打包生成的可執行文件名稱。

對于使用 .spec 文件的項目,可以通過如下命令打包:

pyinstaller --clean <spec_file_name>.spec

4. 依賴項版本不兼容問題

4.1 pyOpenSSLcryptography 的兼容性問題

PyInstaller 打包的項目中,pyOpenSSLcryptography 是常見依賴。由于版本更新問題,某些版本的 pyOpenSSL 可能無法與較新版本的 cryptography 兼容,導致運行時 X509_V_FLAG_NOTIFY_POLICY 等屬性缺失。

常見錯誤

AttributeError: module 'lib' has no attribute 'X509_V_FLAG_NOTIFY_POLICY'

解決方法

  1. 降級 cryptography 版本:建議降級到 3.3.2 版本,確保兼容性。
pip install cryptography==3.3.2
  1. 降級 pyOpenSSL 版本:使用 20.0.1 版本,這與 cryptography 3.3.2 更加兼容。
pip install pyOpenSSL==20.0.1
  1. 升級所有相關依賴:如果使用較舊的版本無效,嘗試升級 selenium-wiremitmproxypyOpenSSL、和 cryptography,確保依賴版本相互兼容。
pip install --upgrade selenium-wire mitmproxy pyOpenSSL cryptography

4.2 chromedriver.exe 打包問題

selenium 使用的 chromedriver.exe 必須在系統的 PATH 中或由代碼顯式指定路徑。然而,打包成單文件后,chromedriver.exe 可能無法正常找到,需要手動配置。

5. 路徑問題及解決方法

5.1 包含 chromedriver.exe 文件

chromedriver.exe 文件放在項目目錄下,并在 .spec 文件的 datas 配置中包含此文件,以確保在打包后可以正確引用。

配置示例

  1. .spec 文件中將 chromedriver.exe 添加到 datas
datas=[('<absolute_path>/chromedriver.exe', '.')  # 打包到可執行文件的根目錄
]
  1. 在代碼中設置相對路徑以引用 chromedriver.exe 文件,確保在打包后的運行環境中可以正確定位到該文件。
from selenium.webdriver.chrome.service import Service
import os
import sysdef resource_path(relative_path):if hasattr(sys, '_MEIPASS'):return os.path.join(sys._MEIPASS, relative_path)return os.path.join(os.path.abspath("."), relative_path)chrome_driver_path = resource_path("chromedriver.exe")
service = Service(executable_path=chrome_driver_path)

6. 詳細解決方案

在打包過程中,還可能遇到其他常見問題,例如文件緩存和打包依賴文件丟失問題。

6.1 清理緩存文件

在打包前,通過 --clean 參數或手動刪除 builddist 文件夾,確保 PyInstaller 不使用緩存文件:

pyinstaller --clean <spec_file_name>.spec

或者手動刪除 builddist 文件夾:

rmdir /s /q build
rmdir /s /q dist

6.2 使用 .spec 文件配置 hiddenimports

如果 PyInstaller 在打包時無法自動識別所有依賴,可以通過 .spec 文件中的 hiddenimports 參數顯式指定依賴項:

hiddenimports=['mitmproxy', 'seleniumwire', 'OpenSSL', 'cryptography'],

6.3 將證書文件包含在打包中

某些依賴(如 selenium-wire)使用的 .crt.key 文件也需手動包含:

datas=[('<absolute_path>/seleniumwire/ca.crt', 'seleniumwire'),('<absolute_path>/seleniumwire/ca.key', 'seleniumwire')
],

7. 調試建議

  1. 確保依賴版本一致:在開發和打包環境中使用相同的依賴版本,防止版本不一致帶來的兼容性問題。
  2. 使用虛擬環境:每個項目單獨配置虛擬環境,避免全局環境中的其他依賴引發沖突。
  3. 分步調試:打包前在開發環境中逐步測試依賴是否正常運行。遇到依賴問題,優先使用兼容的版本組合。

調試依賴沖突

使用 pip check 命令檢查依賴沖突,并通過 pip freeze 獲取依賴列表,以便管理版本:

pip check  # 檢查依賴沖突
pip freeze > requirements.txt  # 保存當前依賴

總結

本指南總結了在使用 PyInstaller 打包 Python 項目時常見的兼容性問題和解決方法。通過以下步驟,可以顯著提升打包的成功率:

  1. 使用兼容的依賴版本,尤其是 pyOpenSSLcryptography
  2. chromedriver.exe 等可執行文件顯式添加到 .spec 文件。
  3. 在代碼中使用 sys._MEIPASS 以正確引用打包后臨時解壓目錄中的文件。

嚴格遵循這些步驟可以有效避免大多數打包和運行時錯誤,確保項目在各個環境下穩定運行。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/77031.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/77031.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/77031.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

(一)棧結構、隊列結構

01-線性結構-數組-棧結構 線性結構&#xff08;Linear List)是由n&#xff08;n>0)個數據元素&#xff08;結點&#xff09; a[0], a[1], a[2], a[3],...,a[n-1]組成的有限序列 數組 通常數組的內存是連續的&#xff0c;所以在知道數組下標的情況下&#xff0c;訪問效率是…

【學Rust寫CAD】35 alpha_mul_256(alpha256.rs補充方法)

源碼 // Calculates (value * alpha256) / 255 in range [0,256], // for [0,255] value and [0,256] alpha256. pub fn alpha_mul_256(self,value: u32) -> Alpha256 {let prod value * self.0;Alpha256((prod (prod >> 8)) >> 8) }代碼分析 這個函數 alph…

C# 與 相機連接

一、通過組件連接相機 需要提前在VisionPro里面保存一個CogAcqFifoTool相機工具為 .vpp 定義一個相機工具 CogAcqFifoTool mAcq null;將保存的相機工具放入mAcq中 string path “C:\Acq.vpp”; mAcq (CogAcqFifoTool)CogSerializer.LoadObjectFrommFile(path);給窗口相機…

Java并發編程高頻面試題

一、基礎概念 1. 并行與并發的區別&#xff1f; 并行&#xff1a;多個任務在多個CPU核心上同時執行&#xff08;物理上同時&#xff09;。并發&#xff1a;多個任務在單CPU核心上交替執行&#xff08;邏輯上同時&#xff09;。類比&#xff1a;并行是多個窗口同時服務&#x…

LiT and Lean: Distilling Listwise Rerankers intoEncoder-Decoder Models

文章&#xff1a;ECIR 2025會議 一、動機 背景&#xff1a;利用LLMs強大的能力&#xff0c;將一個查詢&#xff08;query&#xff09;和一組候選段落作為輸入&#xff0c;整體考慮這些段落的相關性&#xff0c;并對它們進行排序。 先前的研究基礎上進行擴展 [14,15]&#xff0c…

Python高級爬蟲之JS逆向+安卓逆向1.2節: 變量與對象

目錄 引言&#xff1a; 1.2.1 Python中的變量 1.2.2 變量的命名與可讀性 1.2.3 Python中的對象 1.2.4 跟大神學高級爬蟲安卓逆向 引言&#xff1a; 大神薯條老師的高級爬蟲安卓逆向教程&#xff1a; 這套爬蟲教程會系統講解爬蟲的初級&#xff0c;中級&#xff0c;高級知…

可發1區的超級創新思路(python 實現):一種輕量化的動態稀疏門控網絡

首先聲明,該模型為原創!原創!原創!且該思路還未有成果發表,感興趣的小伙伴可以借鑒! 一、應用領域 視頻異常檢測、生成視頻檢測。 二、模型解析 該模型由1.關鍵幀動態選擇機制、2.關鍵幀動態選擇機制以及3.關鍵幀動態選擇機制三大核心組件構成,形成端到端的視頻異常…

使用NVM下載Node.js管理多版本

提示&#xff1a;我解決這個bug跟別人思路可能不太一樣&#xff0c;因為我是之前好用&#xff0c;換個項目就不好使了&#xff0c;倦了 文章目錄 前言項目場景一項目場景二解決方案&#xff1a;下載 nvm安裝 nvm重新下載所需Node 版本nvm常用命令 項目結構說明 前言 提示&…

MySQL數據庫經典面試題解析

1. MySQL 索引使用有哪些注意事項呢? 可以從三個維度回答這個問題:索引哪些情況會失效,索引不適合哪些場景,索引規則 索引哪些情況會失效 查詢條件包含or,可能導致索引失效如何字段類型是字符串,where時一定用引號括起來,否則索引失效like通配符可能導致索引失效。聯合…

C#結合SQLite數據庫使用方法

一、關于SQLite SQLite 是一個輕量級的嵌入式關系型數據庫管理系統&#xff08;RDBMS&#xff09;。與傳統的數據庫管理系統&#xff08;如 MySQL、PostgreSQL 或 SQL Server&#xff09;不同&#xff0c;SQLite 并不需要運行單獨的服務器進程&#xff0c;它的數據庫存儲在一個…

深入解析 MySQL 中的日期時間函數:DATE_FORMAT 與時間查詢優化

深入解析 MySQL 中的日期時間函數&#xff1a;DATE_FORMAT 與時間查詢優化 在數據庫管理和應用開發中&#xff0c;日期和時間的處理是不可或缺的一部分。MySQL 提供了多種日期和時間函數來滿足不同的需求&#xff0c;其中DATE_FORMAT函數以其強大的日期格式化能力&#xff0c;…

如何深刻理解Reactor和Proactor

前言&#xff1a; 網絡框架的設計離不開 I/O 線程模型&#xff0c;線程模型的優劣直接決定了系統的吞吐量、可擴展性、安全性等。目前主流的網絡框架&#xff0c;在網絡 IO 處理層面幾乎都采用了I/O 多路復用方案(又以epoll為主)&#xff0c;這是服務端應對高并發的性能利器。 …

筆試專題(七)

文章目錄 乒乓球筐&#xff08;哈希&#xff09;題解代碼 組隊競賽題解代碼 刪除相鄰數字的最大分數&#xff08;線性dp&#xff09;題解代碼 乒乓球筐&#xff08;哈希&#xff09; 題目鏈接 題解 1. 兩個哈希表 先統計第一個字符串中的字符個數&#xff0c;再統計第二個字…

清晰易懂的 Flutter 卸載和清理教程

以下是為 Flutter 徹底卸載與清理教程&#xff0c;覆蓋 Windows、macOS、Linux 系統&#xff0c;步驟清晰無殘留&#xff0c;確保完全刪除 Flutter SDK、依賴工具及 IDE 配置。 一、通用步驟&#xff1a;確認 Flutter 安裝方式 Flutter 通常通過以下方式安裝&#xff1a; 手動…

關于反卷積

&#x1f9e0; 什么是反卷積&#xff1f; 反卷積&#xff08;Deconvolution&#xff09;&#xff0c;通常也稱為轉置卷積&#xff08;Transpose Convolution&#xff09;&#xff0c;是一種用于擴展輸入特征圖的操作&#xff0c;通常用于生成圖像或上采樣任務中。與標準卷積操…

【機器學習】ROC 曲線與 PR 曲線

目錄 一、混淆矩陣&#xff1a;分類評估的基礎 二. ROC 曲線 (Receiver Operating Characteristic Curve) 三. PR 曲線 (Precision-Recall Curve) 3.1 核心思想 4. 何時使用 ROC 曲線和 PR 曲線&#xff1f; 實驗結果 6. 總結 在機器學習的分類任務中&#xff0c;我們訓…

Python高階函數-map

map() 是 Python 內置的一個高階函數&#xff0c;它接收一個函數和一個可迭代對象作為參數&#xff0c;將函數依次作用在可迭代對象的每個元素上&#xff0c;并返回一個迭代器&#xff08;Python 3.x 中&#xff09;。 基本語法 map(function, iterable, ...)function: 應用于…

上海餐飲市場數據分析與可視化

上海作為中國的經濟中心和國際化大都市,其餐飲市場具有高度的多樣性和競爭性。隨著消費者需求的不斷變化,餐飲行業的從業者和投資者需要深入了解市場現狀和趨勢,以便制定更有效的商業策略。本文將通過數據分析和可視化技術,深入探討上海餐飲市場的現狀和趨勢,為餐飲從業者…

MySQL基礎 [五] - 表的增刪查改

目錄 Create&#xff08;insert&#xff09; Retrieve&#xff08;select&#xff09; where條件 ?編輯 NULL的查詢 結果排序(order by) 篩選分頁結果 (limit) Update Delete 刪除表 截斷表&#xff08;truncate&#xff09; 插入查詢結果&#xff08;insertselect&…

SQL:Primary Key(主鍵)和Foreign Key(外鍵)

目錄 1. Key&#xff08;鍵&#xff09; 2. Index&#xff08;索引&#xff09; 3.Key和Index的區別 4. Primary Key&#xff08;主鍵&#xff09; 5. Foreign Key&#xff08;外鍵&#xff09; 6.主鍵和外鍵的關系 溫馨提示&#xff1a; 閃電按鈕不同的執行功能 首先&…