简体   繁体   English

使用请求库从url上传Python文件

[英]Python file upload from url using requests library

I want to upload a file to an url. 我想将文件上传到网址。 The file I want to upload is not on my computer, but I have the url of the file. 我要上传的文件不在我的电脑上,但我有文件的网址。 I want to upload it using requests library. 我想使用请求库上传它。 So, I want to do something like this: 所以,我想做这样的事情:

url = 'http://httpbin.org/post'
files = {'file': open('report.xls', 'rb')}
r = requests.post(url, files=files)

But, only difference is, the file report.xls comes from some url which is not in my computer. 但是,唯一不同的是,文件report.xls来自一些不在我的计算机中的URL。

The only way to do this is to download the body of the URL so you can upload it. 唯一的方法是下载URL的正文,以便上传它。

The problem is that a form that takes a file is expecting the body of the file in the HTTP POST. 问题是获取file的表单期望HTTP POST中的文件正文。 Someone could write a form that takes a URL instead, and does the fetching on its own… but that would be a different form and request than the one that takes a file (or, maybe, the same form, with an optional file and an optional URL). 有人可以编写一个带有URL的表单,并自己进行提取......但这与采用文件的表单和请求不同(或者,可能是相同的表单,带有可选文件和可选的URL)。

You don't have to download it and save it to a file , of course. 当然,您不必下载它并将其保存到文件中。 You can just download it into memory: 你可以将它下载到内存中:

urlsrc = 'http://example.com/source'
rsrc = requests.get(urlsrc)
urldst = 'http://example.com/dest'
rdst = requests.post(urldst, files={'file': rsrc.content})

Of course in some cases, you might always want to forward along the filename, or some other headers, like the Content-Type . 当然,在某些情况下,您可能始终希望沿着文件名或其他标题(如Content-Type转发。 Or, for huge files, you might want to stream from one server to the other without downloading and then uploading the whole file at once. 或者,对于大型文件,您可能希望从一台服务器流式传输到另一台服务器而无需下载,然后立即上传整个文件。 You'll have to do any such things manually, but almost everything is easy with requests , and explained well in the docs.* 你必须手动完成任何这样的事情,但几乎一切都很容易requests ,并在文档中解释得很好。*


* Well, that last example isn't quite easy … you have to get the raw socket-wrappers off the requests and read and write , and make sure you don't deadlock, and so on… *嗯,最后一个例子并不容易 ......你必须从请求中readwrite原始套接字包装器,并确保你没有死锁,等等......

There is an example in the documentation that may suit you. 文档中有一个可能适合您的示例 A file-like object can be used as a stream input for a POST request. 类文件对象可以用作POST请求的流输入。 Combine this with a stream response for your GET (passing stream=True ), or one of the other options documented here . 将此与您的GET 的流响应 (传递stream=True )或此处记录的其他选项之一相结合。

This allows you to do a POST from another GET without buffering the entire payload locally. 这允许您从另一个GET执行POST而不在本地缓冲整个有效负载。 In the worst case, you may have to write a file-like class as "glue code", allowing you to pass your glue object to the POST that in turn reads from the GET response. 在最坏的情况下,您可能必须编写类似文件的类作为“粘合代码”,允许您将粘合对象传递给POST,而POST又从GET响应中读取。

(This is similar to a documented technique using the Node.js request module.) (这类似于使用Node.js 请求模块的文档化技术 。)

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

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