使用PyInstaller打包后Google Drive API无法正常工作
问题描述
我编写了一段从Google Drive下载压缩包并解压内容的代码,在VS Code中直接运行完全正常,但使用PyInstaller打包成单文件应用后,出现错误提示:
Unable to connect: name: drive version: v3
开启debug模式后,定位到具体错误:
FileNotFoundError:无法找到路径'C:\Users\ALFIEA~1\AppData\Local\Temp_MEI48922\certifi\cacert.pem'
本地存在cacert.pem文件,但不在上述临时路径中,且无法手动将文件粘贴到该路径。使用的PyInstaller打包命令为:
pyinstaller --onefile -w --hidden-import=babel.numbers main.py
解决方案
方法1:手动包含证书文件并指定路径
这是最可靠的生产环境方案,确保证书文件被正确打包且代码能定位到它:
- 先在正常运行的Python环境中执行以下代码,获取本地
cacert.pem的绝对路径:
示例输出:import certifi print(certifi.where())C:\Python39\Lib\site-packages\certifi\cacert.pem - 修改PyInstaller打包命令,添加
--add-data参数将证书文件包含进程序:
注意:Windows系统用分号pyinstaller --onefile -w --hidden-import=babel.numbers --add-data "C:\Python39\Lib\site-packages\certifi\cacert.pem;certifi" main.py;分隔路径,Mac/Linux系统用冒号: - 在初始化Google Drive API客户端的代码中,手动指定证书路径:
import os import sys import certifi from googleapiclient.discovery import build # 判断是否为打包后的运行环境 if getattr(sys, 'frozen', False): # 打包后:从临时目录获取证书 cert_path = os.path.join(sys._MEIPASS, 'certifi', 'cacert.pem') else: # 正常运行:用certifi默认路径 cert_path = certifi.where() # 初始化Drive服务时传入证书路径 drive_service = build('drive', 'v3', credentials=creds, verify=cert_path)
方法2:通过spec文件配置打包
如果需要频繁调整打包参数,使用spec文件更便于维护:
- 生成spec文件:
pyi-makespec --onefile -w --hidden-import=babel.numbers main.py - 打开生成的
main.spec文件,导入certifi并修改datas字段:import certifi a = Analysis( ['main.py'], datas=[(certifi.where(), 'certifi')], # 添加证书文件到打包资源 # 保留原有其他参数... ) - 基于spec文件执行打包:
pyinstaller main.spec
方法3:临时禁用SSL验证(仅测试用)
如果只是临时测试,可跳过证书验证,但生产环境绝对禁止使用,会带来安全风险:
from googleapiclient.discovery import build # 初始化Drive服务时关闭SSL验证 drive_service = build('drive', 'v3', credentials=creds, verify=False)
内容的提问来源于stack exchange,提问作者Programmer12
相关产品推荐
相关产品推荐

