简体   繁体   English

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

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

I have seen the receipes for uploading files via multipartform-data and pycurl .我已经看到了通过multipartform-datapycurl上传文件的收据
Both methods seem to require a file on disk.这两种方法似乎都需要磁盘上的文件。
Can these recipes be modified to supply binary data from memory instead of from disk ?可以修改这些配方以从内存而不是从磁盘提供二进制数据吗?
I guess I could just use a xmlrpc server instead.我想我可以改为使用xmlrpc 服务器
I wanted to get around having to encode and decode the binary data and send it raw...我想绕过必须对二进制数据进行编码和解码并将其原始发送...
Do pycurl and mutlipartform-data work with raw data ? pycurl 和 mutlipartform-data 可以处理原始数据吗?

This (small) library will take a file descriptor, and will do the HTTP POST operation: https://github.com/seisen/urllib2_file/ 这个(小的)库将使用文件描述符,并将执行HTTP POST操作: https : //github.com/seisen/urllib2_file/

You can pass it a StringIO object (containing your in-memory data) as the file descriptor. 您可以将StringIO对象(包含内存中的数据)作为文件描述符传递给它。

Find something that cas work with a file handle. 找到可以与文件句柄一起使用的东西。 Then simply pass a StringIO object instead of a real file descriptor. 然后,只需传递StringIO对象而不是真实文件描述符即可。

I met similar issue today, after tried both and pycurl and multipart/form-data, I decide to read python httplib/urllib2 source code to find out, I did get one comparably good solution: 我今天遇到了类似的问题,在尝试了pycurl和multipart / form-data后,我决定阅读python httplib / urllib2源代码以找出答案,我确实得到了一个相对不错的解决方案:

  1. set Content-Length header(of the file) before doing post 在执行发布之前设置(文件的)Content-Length标头
  2. pass a opened file when doing post 发布时传递打开的文件

Here is the code: 这是代码:

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

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

Following python code works reliable on 2.6.x. 以下python代码在2.6.x上可靠运行。 The input data is of type str. 输入数据为str类型。 Note that the server that receives the data has to loop to read all the data as the large data sizes will be chunked. 请注意,接收到的数据的服务器必须循环读取所有数据,因为大数据量将被分块。 Also attached java code snippet to read the chunked data. 还附加了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()

Java code for the servlet engine: 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.

相关问题 Python HTTP Post,其中包含从Postman生成的上传文件和标头 - Python HTTP Post with upload file and headers generated from Postman python - 使用POST上传文件 - python - upload a file using POST 使用 Python 通过 POST 多部分表单数据上传文件 - Upload file via POST multipart form-data using Python 如何使用Python http.client PUT方法上传二进制/视频文件? - How to upload a binary/video file using Python http.client PUT method? 使用Python将二进制文件上传到postgres服务器 - Using Python to upload a binary file to a postgres server 使用 http 将文件上传到运行 python flask 的服务器时,文件名中的特殊字符丢失 - special character in file name is missing while using http post to upload a file onto server running python flask 使用请求的Python HTTP请求二进制数据 - Python HTTP Request Binary Data using Requests 如何使用python从传入的HTTP POST中提取数据 - How to extract data from incoming HTTP POST using python 使用 Python 请求 POST 二进制(视频)文件 - POST Binary (video) File Using Python Requests 使用 Python urllib/urllib2 发出 http POST 请求以上传文件 - Make an http POST request to upload a file using Python urllib/urllib2
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM