点击关注我的Telegram群组和微信公众号

MENU

解决Python requests库打包后出现缺少CA证书的错误

2022 年 04 月 13 日 • 阅读: 391 • 技术,教程

前言

PyInstaller 是一个强大而使用简单的 Python 代码打包程序,使用它,我们可以快速将代码打包成可执行程序。但是,如果代码中包含requests库,则打包后的程序会出现OSError: Could not find a suitable TLS CA certificate bundle, invalid path:。这一问题出现的原因是在打包时,requests库释放在用户临时文件夹内的CA证书没有被一起打包,所以解决的思路就是将证书手动加入代码内。

cacert.pem文件可以从https://curl.se/docs/caextract.html下载到

解决方案1

来自StackOverflow一搜就能找到的方法是将CA证书的路径临时地写入系统环境变量中

import sys, os


def override_where():
    """ overrides certifi.core.where to return actual location of cacert.pem"""
    # change this to match the location of cacert.pem
    return os.path.abspath("cacert.pem")


# is the program compiled?
if hasattr(sys, "frozen"):
    import certifi.core

    os.environ["REQUESTS_CA_BUNDLE"] = override_where()
    certifi.core.where = override_where

    # delay importing until after where() has been replaced
    import requests.utils
    import requests.adapters
    # replace these variables in case these modules were
    # imported before we replaced certifi.core.where
    requests.utils.DEFAULT_CA_BUNDLE_PATH = override_where()
    requests.adapters.DEFAULT_CA_BUNDLE_PATH = override_where()

加入如下代码后,将cacert.pem置于打包完成后的exe文件同目录即可使exe可执行程序正常运行了

解决方法2

上述方法,能够解决标题中的问题,但是我们将不得不将一个pem证书和可执行文件捆绑在一起。所以,一个有点奇怪的方式是将证书内容保存为一个Python变量值,在主程序内将该值写入到一个临时文件中,再将该临时文件加入系统环境变量中,这样便可解决方法1所带来的问题。
cert.py中,我们写入证书内容

CERT_DATA = """
证书内容

"""

在主程序main.py

import tempfile
import os, sys

from cert import CERT_DATA 

temp_cert = tempfile.NamedTemporaryFile(delete=False, encoding="utf-8", mode="w")
temp_cert.write(CERT_DATA)
temp_cert.flush()
os.environ['REQUESTS_CA_BUNDLE'] = temp_cert.name

再次执行Pyinstaller -F main.py,新的可执行文件便可以顺利运行了

返回文章列表 文章二维码 打赏
本页链接的二维码
打赏二维码