You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyInstaller打包后Python Multipart POST文件上传失效问题求助

Excel文件上传打包后失效的解决方案

问题描述

使用Tkinter选择Excel文件后,通过requests发送POST请求上传文件,在VS Code中直接运行Python脚本时一切正常,但经PyInstaller打包为exe后,请求返回状态码200,却未成功上传文件,怀疑是路径或文件句柄相关问题。

原代码

Tkinter选择文件代码

from tkinter import filedialog

self.file = filedialog.askopenfile(
            mode="r", filetypes=[("Excel files", ".xlsx .xls")]
        )

POST请求上传代码

import os
import json
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder

field_data = {
    "data": (None, json.dumps(data), "application/json"),
    "file": (
        os.path.basename(file.name),
        open(os.path.abspath(file.name), "rb"),
        "multipart/form-data",
    ),
}
m = MultipartEncoder(fields=field_data)
headers = {"Content-Type": m.content_type}

API_ENDPOINT = "https://uploadfile"

session = requests.Session()
session.trust_env = False
r = session.post(url=API_ENDPOINT, data=m, headers=headers)

解决方案

1. 修正文件打开模式与复用文件对象

原代码中askopenfile使用文本模式"r",上传文件需要二进制模式;同时重复打开文件可能导致打包后出现文件句柄异常,直接复用已打开的文件对象即可:

  • 将askopenfile的mode改为"rb"
  • POST请求中直接使用已打开的self.file对象,无需再次调用open

2. 重置文件指针位置

文件打开后如果有过读取操作,指针会停在文件末尾,上传前需要将指针重置到开头:

self.file.seek(0)

3. 优化MIME类型与路径处理

  • filedialog.askopenfile返回的文件对象的name属性已经是绝对路径,无需额外调用os.path.abspath
  • 替换multipart/form-data为更准确的Excel MIME类型(.xlsx用application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,.xls用application/vnd.ms-excel)

修改后的完整代码

Tkinter选择文件部分

from tkinter import filedialog

self.file = filedialog.askopenfile(
            mode="rb", filetypes=[("Excel files", ".xlsx .xls")]
        )

POST请求上传部分

import os
import json
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder

# 重置文件指针到开头
self.file.seek(0)

# 根据文件后缀设置正确的MIME类型
file_ext = os.path.splitext(self.file.name)[1].lower()
mime_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" if file_ext == ".xlsx" else "application/vnd.ms-excel"

field_data = {
    "data": (None, json.dumps(data), "application/json"),
    "file": (
        os.path.basename(self.file.name),
        self.file,
        mime_type,
    ),
}
m = MultipartEncoder(fields=field_data)
headers = {"Content-Type": m.content_type}

API_ENDPOINT = "https://uploadfile"

session = requests.Session()
session.trust_env = False
r = session.post(url=API_ENDPOINT, data=m, headers=headers)

# 上传完成后关闭文件,释放资源
self.file.close()

额外打包注意事项

打包时需确保PyInstaller包含requests_toolbelt依赖,可通过以下命令打包:

pyinstaller --hidden-import requests_toolbelt.multipart.encoder your_script.py

内容的提问来源于stack exchange,提问作者shfshfdl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 11:04:49