Python中tinypng接口模块tinify打包exe后连不上网络的问题

最近用 tinypng 提供的 python 模块 tinify 写了个在线压缩图片的程序,正常 python 环境调用脚本运行是没有问题,但是打包成 exe 后,调用接口就直接抛出 ConnectionError 错误,死活连不上

cx_freeze、pyinstaller 打包 exe 都试过了,还是同样的问题

google、baidu、bing 了好久,还没找到解决方案,有没有遇到过相同问题的,求指导
Python中tinypng接口模块tinify打包exe后连不上网络的问题

2 回复

我遇到过类似的问题,打包成exe后网络请求失败,通常是SSL证书或网络库的问题。试试这个解决方案:

import tinify
import ssl
import os

# 方法1:设置自定义CA证书(推荐)
def setup_tinify_with_ssl():
    # 获取当前脚本所在目录
    current_dir = os.path.dirname(os.path.abspath(__file__))
    
    # 创建cacert.pem文件路径(放在exe同级目录)
    cert_path = os.path.join(current_dir, "cacert.pem")
    
    # 如果cacert.pem不存在,从requests库复制或下载
    if not os.path.exists(cert_path):
        # 从certifi库获取证书(如果安装了certifi)
        try:
            import certifi
            with open(certifi.where(), 'rb') as src:
                with open(cert_path, 'wb') as dst:
                    dst.write(src.read())
        except:
            # 或者手动下载cacert.pem放到exe目录
            pass
    
    # 设置tinify的API key
    tinify.key = "YOUR_API_KEY"
    
    # 创建自定义SSL上下文
    ssl_context = ssl.create_default_context()
    ssl_context.load_verify_locations(cert_path)
    
    # 设置tinify使用自定义SSL上下文
    # 注意:tinify库本身可能不直接支持SSL上下文设置
    # 可能需要通过修改底层请求库的配置
    
# 方法2:使用代理绕过SSL验证(仅用于测试)
def setup_tinify_with_proxy():
    import requests
    from requests.adapters import HTTPAdapter
    
    tinify.key = "YOUR_API_KEY"
    
    # 创建自定义会话
    session = requests.Session()
    
    # 禁用SSL验证(不推荐生产环境使用)
    session.verify = False
    
    # 设置重试策略
    adapter = HTTPAdapter(max_retries=3)
    session.mount('https://', adapter)
    
    # 这里需要修改tinify的内部请求方式
    # 通常需要查看tinify源码,找到它使用的请求库

# 方法3:打包时包含所有依赖(PyInstaller配置)
"""
在PyInstaller spec文件或命令行中添加:
--add-data "path/to/certifi/cacert.pem;."
--hidden-import certifi
--hidden-import ssl
"""

如果上面的方法不行,更直接的解决方案是修改打包命令:

# 使用PyInstaller打包时添加这些参数
pyinstaller --onefile \
    --add-data "C:\Python39\Lib\site-packages\certifi\cacert.pem;certifi" \
    --hidden-import certifi \
    --hidden-import urllib3 \
    --hidden-import requests \
    your_script.py

或者在代码开头添加:

# 在导入tinify之前设置
import os
os.environ['REQUESTS_CA_BUNDLE'] = os.path.join(os.path.dirname(__file__), 'cacert.pem')
os.environ['SSL_CERT_FILE'] = os.path.join(os.path.dirname(__file__), 'cacert.pem')

主要问题是PyInstaller打包时没把SSL证书文件包含进去,手动带上证书文件就能解决。

总结:打包时带上SSL证书文件就能解决网络连接问题。


嗯?难道只有我的 tinypng 是要坐飞机的?

回到顶部