Python项目打包指南:PyInstaller与SeleniumWire的兼容性挑战及解决方案

前言

前段时间做一个内网开发的需求,要求将selenium程序打包成.exe放在内网的win7上运行,在掘金搜了一圈也没有发现相关文章,因此将过程中踩到的坑记录分享一下。

本文涵盖了具体打包操作、不同模块和依赖项的兼容性解决方案,以确保在打包和运行时都能正常工作。


1. 背景

在 Python 项目中,使用第三方库(如 selenium、selenium-wire、mitmproxy 等)时,会遇到许多依赖项,并且由于库之间的版本兼容性问题,可能导致运行时错误。常用的打包工具 PyInstaller 能将 Python 项目打包成单个可执行文件,但也会因为兼容性问题和路径管理而出现各种运行错误。因此,本指南总结了打包过程中常见问题和解决方案,以帮助开发者顺利完成项目的打包和发布。

2. 可能遇到的问题概述

在PyInstaller打包selenium-wire时可能会遇到一些问题,如下:

  1. 依赖冲突:如 pyOpenSSL 与 cryptography 的版本冲突问题。
  2. 路径问题:如 chromedriver.exe 在运行时未找到或未正确加载。
  3. 打包文件缺失:某些文件(如 .crt、.key、chromedriver.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 pyOpenSSL 和 cryptography 的兼容性问题

在 PyInstaller 打包的项目中,pyOpenSSL 和 cryptography 是常见依赖。由于版本更新问题,某些版本的 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-wire、mitmproxy、pyOpenSSL、和 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 参数或手动删除 build 和 dist 文件夹,确保 PyInstaller 不使用缓存文件:

pyinstaller --clean <spec_file_name>.spec

或者手动删除 build 和 dist 文件夹:

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. 使用兼容的依赖版本,尤其是 pyOpenSSL 和 cryptography。
  2. 将 chromedriver.exe 等可执行文件显式添加到 .spec 文件。
  3. 在代码中使用 sys._MEIPASS 以正确引用打包后临时解压目录中的文件。

严格遵循这些步骤可以有效避免大多数打包和运行时错误,确保项目在各个环境下稳定运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.tpcf.cn/diannao/77031.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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; 闪电按钮不同的执行功能 首先&…