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 项目时,可以通过以下步骤和命令来生成可执行文件:

css 复制代码
pyinstaller --onefile --clean --hidden-import=<module> --name=<executable_name> <script.py>

参数详解:

  • --onefile:将所有文件打包成一个独立可执行文件。
  • --clean:清理之前打包时的缓存,确保使用最新的依赖版本。
  • --hidden-import:指定打包时包含的隐藏模块(PyInstaller 有时无法自动检测到的依赖)。
  • --name:指定打包生成的可执行文件名称。

对于使用 .spec 文件的项目,可以通过如下命令打包:

css 复制代码
pyinstaller --clean <spec_file_name>.spec

4. 依赖项版本不兼容问题

4.1 pyOpenSSLcryptography 的兼容性问题

PyInstaller 打包的项目中,pyOpenSSLcryptography 是常见依赖。由于版本更新问题,某些版本的 pyOpenSSL 可能无法与较新版本的 cryptography 兼容,导致运行时 X509_V_FLAG_NOTIFY_POLICY 等属性缺失。

常见错误

arduino 复制代码
AttributeError: module 'lib' has no attribute 'X509_V_FLAG_NOTIFY_POLICY'

解决方法

  1. 降级 cryptography 版本 :建议降级到 3.3.2 版本,确保兼容性。
ini 复制代码
pip install cryptography==3.3.2
  1. 降级 pyOpenSSL 版本 :使用 20.0.1 版本,这与 cryptography 3.3.2 更加兼容。
ini 复制代码
pip install pyOpenSSL==20.0.1
  1. 升级所有相关依赖 :如果使用较旧的版本无效,尝试升级 selenium-wiremitmproxypyOpenSSL、和 cryptography,确保依赖版本相互兼容。
sql 复制代码
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
ini 复制代码
datas=[
    ('<absolute_path>/chromedriver.exe', '.')  # 打包到可执行文件的根目录
]
  1. 在代码中设置相对路径以引用 chromedriver.exe 文件,确保在打包后的运行环境中可以正确定位到该文件。
lua 复制代码
from selenium.webdriver.chrome.service import Service
import os
import sys

def 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 不使用缓存文件:

css 复制代码
pyinstaller --clean <spec_file_name>.spec

或者手动删除 builddist 文件夹:

bash 复制代码
rmdir /s /q build
rmdir /s /q dist

6.2 使用 .spec 文件配置 hiddenimports

如果 PyInstaller 在打包时无法自动识别所有依赖,可以通过 .spec 文件中的 hiddenimports 参数显式指定依赖项:

ini 复制代码
hiddenimports=['mitmproxy', 'seleniumwire', 'OpenSSL', 'cryptography'],

6.3 将证书文件包含在打包中

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

ini 复制代码
datas=[
    ('<absolute_path>/seleniumwire/ca.crt', 'seleniumwire'),
    ('<absolute_path>/seleniumwire/ca.key', 'seleniumwire')
],

7. 调试建议

  1. 确保依赖版本一致:在开发和打包环境中使用相同的依赖版本,防止版本不一致带来的兼容性问题。
  2. 使用虚拟环境:每个项目单独配置虚拟环境,避免全局环境中的其他依赖引发冲突。
  3. 分步调试:打包前在开发环境中逐步测试依赖是否正常运行。遇到依赖问题,优先使用兼容的版本组合。

调试依赖冲突

使用 pip check 命令检查依赖冲突,并通过 pip freeze 获取依赖列表,以便管理版本:

bash 复制代码
pip check  # 检查依赖冲突
pip freeze > requirements.txt  # 保存当前依赖

总结

本指南总结了在使用 PyInstaller 打包 Python 项目时常见的兼容性问题和解决方法。通过以下步骤,可以显著提升打包的成功率:

  1. 使用兼容的依赖版本,尤其是 pyOpenSSLcryptography
  2. chromedriver.exe 等可执行文件显式添加到 .spec 文件。
  3. 在代码中使用 sys._MEIPASS 以正确引用打包后临时解压目录中的文件。

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

相关推荐
AOwhisky10 分钟前
Python 学习笔记(第六期)——函数:定义、参数传递与作用域
笔记·python·学习·云原生·运维开发·函数·参数传递
茗创科技38 分钟前
CGE连接组:用基因表达解码脑疾病的异质性(附高分文献下载)
python·matlab·脑网络
汤米粥40 分钟前
Python调用百度搜索触发安全验证
开发语言·python
杠杠的blog1 小时前
企业级提示词管理
python·agent·提示词·生产级实践
小小放舟、1 小时前
VS Code Code Runner 中文乱码修复与 IDEA 风格输出配置
vscode·python·code runner
俺不中嘞2 小时前
python常用函数
开发语言·python
薛定猫AI2 小时前
【技术干货】大模型文档结构化提取实战:Python解析PDF发票并批量生成CSV
java·python·pdf
zhiSiBuYu05172 小时前
RAG 性能优化与缓存策略实战指南
人工智能·python·机器学习
ClouGence2 小时前
8 款好用的 Web 自动化测试工具大盘点:怎么选、适合谁?
selenium·测试
荣码2 小时前
Prompt工程实战:同一个需求换3种写法,效果差10倍
java·python