繁体   English   中英

使用 python http post 从内存上传二进制数据或文件

[英]upload binary data or file from memory using python http post

我已经看到了通过multipartform-datapycurl上传文件的收据
这两种方法似乎都需要磁盘上的文件。
可以修改这些配方以从内存而不是从磁盘提供二进制数据吗?
我想我可以改为使用xmlrpc 服务器
我想绕过必须对二进制数据进行编码和解码并将其原始发送...
pycurl 和 mutlipartform-data 可以处理原始数据吗?

这个(小的)库将使用文件描述符,并将执行HTTP POST操作: https : //github.com/seisen/urllib2_file/

您可以将StringIO对象(包含内存中的数据)作为文件描述符传递给它。

找到可以与文件句柄一起使用的东西。 然后,只需传递StringIO对象而不是真实文件描述符即可。

我今天遇到了类似的问题,在尝试了pycurl和multipart / form-data后,我决定阅读python httplib / urllib2源代码以找出答案,我确实得到了一个相对不错的解决方案:

  1. 在执行发布之前设置(文件的)Content-Length标头
  2. 发布时传递打开的文件

这是代码:

import urllib2, os
image_path = "png\\01.png"
url = 'http://xx.oo.com/webserviceapi/postfile/'
length = os.path.getsize(image_path)
png_data = open(image_path, "rb")
request = urllib2.Request(url, data=png_data)
request.add_header('Cache-Control', 'no-cache')
request.add_header('Content-Length', '%d' % length)
request.add_header('Content-Type', 'image/png')
res = urllib2.urlopen(request).read().strip()
return res

看到我的博客文章: http : //www.2maomao.com/blog/python-http-post-a-binary-file-using-urllib2/

以下python代码在2.6.x上可靠运行。 输入数据为str类型。 请注意,接收到的数据的服务器必须循环读取所有数据,因为大数据量将被分块。 还附加了Java代码段以读取分块的数据。

def post(self, url, data):
    self.curl = pycurl.Curl()
    self.response_headers = StringIO.StringIO()
    self.response_body = io.BytesIO()
    self.curl.setopt(pycurl.WRITEFUNCTION, self.response_body.write)
    self.curl.setopt(pycurl.HEADERFUNCTION, self.response_headers.write)
    self.curl.setopt(pycurl.FOLLOWLOCATION, 1)
    self.curl.setopt(pycurl.MAXREDIRS, 5)
    self.curl.setopt(pycurl.TIMEOUT, 60)
    self.curl.setopt(pycurl.ENCODING,"deflate, gzip")
    self.curl.setopt(pycurl.URL, url)
    self.curl.setopt(pycurl.VERBOSE, 1)
    self.curl.setopt(pycurl.POST,1)
    self.curl.setopt(pycurl.POSTFIELDS,data)
    self.curl.setopt(pycurl.HTTPHEADER, [ "Content-Type: octate-stream" ])
    self.curl.setopt(pycurl.POSTFIELDSIZE, len(data))
    self.curl.perform()
    return url, self.curl.getinfo(pycurl.RESPONSE_CODE),self.response_headers.getvalue(), self.response_body.getvalue()

Servlet引擎的Java代码:

int postSize = Integer.parseInt(req.getHeader("Content-Length"));
results = new byte[postSize];
int read = 0;
while(read < postSize) {
      int n = req.getInputStream().read(results);
      if (n < 0) break;
      read += n;
  }

找到了一个适用于cherrypy文件上传示例的解决方案: urllib2-binary-upload.py

import io         # Part of core Python
import requests   # Install via: 'pip install requests'

# Get the data in bytes. I got it via:
#   with open("smile.gif", "rb") as fp: data = fp.read()
data = b"GIF89a\x12\x00\x12\x00\x80\x01\x00\x00\x00\x00\xff\x00\x00!\xf9\x04\x01\n\x00\x01\x00,\x00\x00\x00\x00\x12\x00\x12\x00\x00\x024\x84\x8f\x10\xcba\x8b\xd8ko6\xa8\xa0\xb3Wo\xde9X\x18*\x15x\x99\xd9'\xad\x1b\xe5r(9\xd2\x9d\xe9\xdd\xde\xea\xe6<,\xa3\xd8r\xb5[\xaf\x05\x1b~\x8e\x81\x02\x00;"

# Hookbin is similar to requestbin - just a neat little service
# which helps you to understand which queries are sent
url = 'https://hookb.in/je2rEl733Yt9dlMMdodB'

in_memory_file = io.BytesIO(data)
response = requests.post(url, files=(("smile.gif", in_memory_file),))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM