【问题标题】:Python Requests - Post a zip file with multipart/form-dataPython 请求 - 使用 multipart/form-data 发布一个 zip 文件
【发布时间】:2013-08-15 00:16:04
【问题描述】:

我正在玩 Python Requests 模块,到目前为止这很有趣。

但是,我在尝试使用 multipart/form-data 发布 zip 文件时遇到了问题。

我正在使用 Digest 身份验证,并且能够成功发布其他文件类型,例如.xls 等

我正在使用以下方式创建发布请求:

file = open('/Users/.../test.zip', 'rb').read()
r = requests.post(url, auth=HTTPDigestAuth('dev', 'dev'), data = {"mysubmit":"Go"}, files={"archive": ("test.zip", file)})

这会出错并给出:

requests.exceptions.ConnectionError: HTTPConnectionPool(host='10.2.2.70', port=80): Max retries exceeded with url: /plugin_install 
(Caused by <class 'socket.error'>: [Errno 32] Broken pipe)

我尝试过使用较小的 zip 文件并更改数据/文件值,但发生了同样的错误。

我是否遗漏了一些明显的东西?

感谢您提供的任何启发!

【问题讨论】:

  • 你用s = request.Session; s.auth...; s.post(...)试过了吗?

标签: python post python-requests


【解决方案1】:

requests 而言,zip 文件和任何其他二进制数据块之间没有区别

你的服务器在这里坏了;当您向其发送 zip 文件时,它正在切断连接。这不是 requests 可以做的任何事情。

当您遇到此类问题时,您可能需要针对 http://httpbin.org/ 进行测试;是requests库作者搭建的测试服务。

另一个提示:发送时不需要将整个文件对象读入内存。只需将对象本身传递给requests

fileobj = open('/Users/.../test.zip', 'rb')
r = requests.post(url, auth=HTTPDigestAuth('dev', 'dev'), data = {"mysubmit":"Go"}, files={"archive": ("test.zip", fileobj)})

针对httpbin.org的演示:

>>> import requests
>>> fileobj = open('/tmp/test.zip', 'rb')
>>> r = requests.post('http://httpbin.org/post', data={"mysubmit":"Go"}, files={"archive": ("test.zip", fileobj)})
>>> r
<Response [200]>
>>> r.json()
{u'origin': u'217.32.203.188', u'files': {u'archive': u'data:application/zip;base64,<long base64 body omitted>'}, u'form': {u'mysubmit': u'Go'}, u'url': u'http://httpbin.org/post', u'args': {}, u'headers': {u'Content-Length': u'57008', u'Accept-Encoding': u'gzip, deflate, compress', u'Connection': u'close', u'Accept': u'*/*', u'User-Agent': u'python-requests/1.2.3 CPython/2.7.5 Darwin/12.4.0', u'Host': u'httpbin.org', u'Content-Type': u'multipart/form-data; boundary=9aec1d03a1794177a38b48416dd4c811'}, u'json': None, u'data': u''}

【讨论】:

  • 请注意,您可以直接发送文件对象,仍然使用元组来提供文件名。
  • @Lukasa:快速重新测试,很明显我犯了一个错误;我一定已经读过文件对象并且忘记回溯到 0..
  • 感谢您的回复!您的澄清肯定有帮助,因为我现在可以成功发布小 zip 文件。不过,在发布任何大于 98 KB 的 zip 文件时,我似乎仍然遇到该错误。这可能是请求/urllib3 超时/内容长度问题吗?
  • @BenjiBarash:不,这仍然是服务器端问题。
  • 我以前使用过一个名为 Poster 的库,但它并没有在服务器上提示这些问题。海报调用了一个函数 multipart_encode,然后我将 urllib2.Request 与它生成的数据一起使用。我找到了 Requests,因为 Poster 在使用 Digest Auth 时遇到了 multipart/form-data 问题。 bitbucket.org/chrisatlee/poster/issue/7/…
【解决方案2】:

如果您在上传 zip 文件时遇到任何错误: 此问题可能是由标题上的 'Content-Type': 'multipart/form-data' 设置引起的。 可以通过删除此设置来解决问题,如下例所示:

header = {'Content-Type': 'multipart/form-data', 'Authorization': 'Bearer {}'.format(bearerToken)}

改成:

header = {'Authorization': 'Bearer {}'.format(bearerToken)}

对我有用的代码:

 header = {"INFA-SESSION-ID":self._v3SessionID}
 files = {'package': ("response.zip", open("C:\Users\myUser\Downloads\response.zip", 'rb'),'application/zip')}
 response = re.post(url, headers=header, files=files)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多