Python上传XML文件 requests库如何post一个文件

正确写法是用 files 参数传 XML 文件,如 files={'file': ('config.xml', f, 'application/xml')};不能用 data 或 json,否则服务端收不到原始 XML 内容,且 data 接收文件对象会转为字符串而非字节流。

requests.post 上

传 XML 文件的正确写法

直接用 files 参数传 XML 文件,不是用 datajson。否则服务端收不到原始 XML 内容,或被自动序列化成字符串、丢失根标签和声明。

为什么不能用 data=open(...)

常见错误是把文件对象塞进 data,比如 data=open('a.xml', 'rb') —— 这会让 requests 把文件对象转成字符串(如 <_io.bufferedreader name="a.xml">),根本不是 XML 内容。

  • data 适合传 raw 字节或字符串,不带文件名、无 Content-Disposition
  • files 才会构造 multipart/form-data,带上文件名和类型,服务端才能当「上传文件」处理
  • XML 文件没有固定 MIME 类型,但建议显式设为 application/xmltext/xml

完整上传示例(含文件名与类型)

关键点:用 files 构造二元组 (field_name, (filename, file_obj, content_type)),其中 field_name 必须和服务端约定一致(比如后端 expecting file 字段)。

import requests

with open('config.xml', 'rb') as f:
    files = {
        'file': ('config.xml', f, 'application/xml')
    }
    response = requests.post(
        'https://api.example.com/upload',
        files=files
    )
print(response.status_code)
print(response.text)

容易踩的坑

XML 文件开头有 BOM 或编码不匹配时,服务端解析可能失败,但错误常不明确。

  • 确保用 'rb' 模式打开,避免文本模式自动换行符转换
  • 如果 XML 声明是 ,但文件实际是 UTF-8 with BOM,部分服务端会报「invalid token」——用 open(..., 'rb').read().lstrip(b'\xef\xbb\xbf') 去 BOM
  • 某些 API 要求 XML 必须放在 form 的特定字段(如 upload_file),而不是通用 file,字段名错就 400
  • 不用 headers={'Content-Type': 'multipart/form-data'} —— requests 会自动生成带 boundary 的正确头,手动设反而破坏 multipart 结构
XML 上传本身不复杂,难点常在服务端对字段名、MIME 类型、编码、BOM 的隐性要求,建议先用 curl 验证成功再迁移到 Python。