SSL证书验证失败

问题描述

当我在pip install scrapy 的时候,发生如下报错:

(.venv) xieshaolin@xieshaolindeMacBook-Pro PythonLearning % pip install scrapy  
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1028)'))': /simple/scrapy/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1028)'))': /simple/scrapy/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1028)'))': /simple/scrapy/
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1028)'))': /simple/scrapy/
WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1028)'))': /simple/scrapy/
Could not fetch URL https://pypi.org/simple/scrapy/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/scrapy/ (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1028)'))) - skipping
ERROR: Could not find a version that satisfies the requirement scrapy (from versions: none)
ERROR: No matching distribution found for scrapy

原因

pip install scrapy 失败的原因是 SSL 证书验证失败,导致无法连接到 PyPI(Python Package Index)下载 pygame。这个问题通常与网络环境系统配置有关。

为什么需要 SSL 证书?

SSL(Secure Sockets Layer)证书用于加密客户端(如你的电脑)和服务器(如 PyPI)之间的通信,确保数据传输的安全性。具体作用包括:

  1. 身份验证:验证服务器的身份,确保你连接的是合法的服务器,而不是恶意仿冒的服务器。
  2. 数据加密:加密传输的数据,防止数据被窃取或篡改。
  3. 完整性保护:确保数据在传输过程中没有被修改。

在 Python 中,pip 使用 HTTPS 连接到 PyPI 下载包。如果 SSL 证书缺失或配置不正确,pip 无法验证服务器的身份,从而导致 SSLError 错误。

措施

网络环境

国内镜像

由于网络问题,连接到 PyPI 官方源可能会失败。可以尝试使用国内的镜像源(如清华源、阿里云源等)来安装 scrapy

使用清华源安装:

pip install scrapy -i https://pypi.tuna.tsinghua.edu.cn/simple

使用阿里云源安装:

pip install scrapy -i https://mirrors.aliyun.com/pypi/simple

忽略 SSL 验证(不推荐)

如果镜像源仍然无法解决问题,可以尝试忽略 SSL 验证。不过,这种方法存在安全风险,建议仅在测试环境中使用。

pip install scrapy --trusted-host pypi.org --trusted-host files.pythonhosted.org

系统配置

如何检查 macOS 是否缺少 SSL 证书?

xieshaolin@xieshaolindeMacBook-Pro bin % python3 -c "import ssl; print(ssl.get_default_verify_paths())"
DefaultVerifyPaths(cafile=None, capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/Library/Frameworks/Python.framework/Versions/3.13/etc/openssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/Library/Frameworks/Python.framework/Versions/3.13/etc/openssl/certs')

cafilecapath 的值为 None 或路径不存在,说明 SSL 证书配置有问题。

注意Python版本的影响

xieshaolin@xieshaolindeMacBook-Pro ssl % python -c "import ssl; print(ssl.get_default_verify_paths())"
DefaultVerifyPaths(cafile='/private/etc/ssl/cert.pem', capath='/private/etc/ssl/certs', openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/private/etc/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/private/etc/ssl/certs')

刚开始我执行的是python -c "import ssl; print(ssl.get_default_verify_paths())"

执行的结果显示cafile='/private/etc/ssl/cert.pem', capath='/private/etc/ssl/certs'

于是我认为我的Python配置没有问题。

但是这个是python2的配置,不是我执行的Python3的配置

如果想看Python3的配置,需要执行:python3 -c "import ssl; print(ssl.get_default_verify_paths())"

检查证书文件是否存在

检查 /Library/Frameworks/Python.framework/Versions/3.13/etc/openssl/cert.pem

  1. 打开终端,运行以下命令:

    ls /Library/Frameworks/Python.framework/Versions/3.13/etc/openssl/cert.pem
    
  2. 如果文件存在,检查文件内容:

    cat /Library/Frameworks/Python.framework/Versions/3.13/etc/openssl/cert.pem
    
    • 确保文件内容包含有效的 SSL 证书(以 -----BEGIN CERTIFICATE----- 开头,以 -----END CERTIFICATE----- 结尾)。
    • 如果文件内容无效,可以手动替换为从 curl 官方网站 下载的 cacert.pem 文件。
  3. 如果文件不存在,可以手动创建并复制证书文件:

    sudo mkdir -p /Library/Frameworks/Python.framework/Versions/3.13/etc/openssl
    sudo cp /path/to/cacert.pem /Library/Frameworks/Python.framework/Versions/3.13/etc/openssl/cert.pem
    

    (将 /path/to/cacert.pem 替换为实际的证书文件路径)。

设置环境变量

临时设置环境变量

  1. 打开终端,运行以下命令:

    export SSL_CERT_FILE=/Library/Frameworks/Python.framework/Versions/3.13/etc/openssl/cert.pem
    
  2. 验证环境变量是否设置成功:

    echo $SSL_CERT_FILE
    

    输出应为:

    /Library/Frameworks/Python.framework/Versions/3.13/etc/openssl/cert.pem
    
  3. 测试 pip 是否正常工作:

    pip install requests
    

    如果没有出现 SSL 错误,说明问题已解决。

永久设置环境变量

如果临时设置环境变量有效,可以将其永久添加到你的 shell 配置文件中。

  1. 打开 shell 配置文件:

    • 如果你使用 zsh(macOS 默认):

      nano ~/.zshrc
      
    • 如果你使用 bash

      nano ~/.bashrc
      
  2. 在文件末尾添加以下内容:

    export  SSL_CERT_FILE=/Library/Frameworks/Python.framework/Versions/3.13/etc/openssl/cert.pem
    
  3. 保存并退出编辑器:

    • nano 中,按 Ctrl + X,然后按 Y 确认保存。
  4. 使配置生效:

    source ~/.zshrc  # 或 source ~/.bashrc
    
  5. 验证环境变量是否设置成功:

    echo $SSL_CERT_FILE
    

    输出应为:

    /Library/Frameworks/Python.framework/Versions/3.13/etc/openssl/cert.pem
    

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1909773034@qq.com

×

喜欢就点赞,疼爱就打赏