我正在执行使用Python请求库上传文件的简单任务。我搜索了Stack Overflow,似乎没有人有同样的问题,即文件没有被服务器接收到:
import requests
url='http://nesssi.cacr.caltech.edu/cgi-bin/getmulticonedb_release2.cgi/post'
files={'files': open('file.txt','rb')}
values={'upload_file' : 'file.txt' , 'DB':'photcat' , 'OUT':'csv' , 'SHORT':'short'}
r=requests.post(url,files=files,data=values)
我用我的文件名填充'upload_file'关键字的值,因为如果我让它为空,它说
Error - You must select a file to upload!
现在我得到
File file.txt of size bytes is uploaded successfully!
Query service results: There were 0 lines.
只有当文件为空时才会出现。所以我不知道如何成功地发送我的文件。我知道这个文件是有效的,因为如果我去这个网站,手动填写表单,它会返回一个匹配对象的列表,这就是我想要的。我很感激所有的提示。
其他一些相关的话题(但没有回答我的问题):
从Python脚本中使用POST发送文件
http://docs.python-requests.org/en/latest/user/quickstart/#response-content
使用请求上传文件并发送额外数据
http://docs.python-requests.org/en/latest/user/advanced/#body-content-workflow
如果upload_file是文件,使用:
files = {'upload_file': open('file.txt','rb')}
values = {'DB': 'photcat', 'OUT': 'csv', 'SHORT': 'short'}
r = requests.post(url, files=files, data=values)
和请求将发送一个由多个部分组成的表单POST体,其中upload_file字段设置为file.txt文件的内容。
文件名将包含在特定字段的mime头中:
>>> import requests
>>> open('file.txt', 'wb') # create an empty demo file
<_io.BufferedWriter name='file.txt'>
>>> files = {'upload_file': open('file.txt', 'rb')}
>>> print(requests.Request('POST', 'http://example.com', files=files).prepare().body.decode('ascii'))
--c226ce13d09842658ffbd31e0563c6bd
Content-Disposition: form-data; name="upload_file"; filename="file.txt"
--c226ce13d09842658ffbd31e0563c6bd--
注意filename="file.txt"参数。
如果需要更多的控制,可以使用包含2到4个元素的元组作为文件映射值。第一个元素是文件名,后面跟着内容,一个可选的内容类型头值和一个可选的附加头的映射:
files = {'upload_file': ('foobar.txt', open('file.txt','rb'), 'text/x-spam')}
这设置了一个可选的文件名和内容类型,省略了可选的头文件。
如果您的意思是从一个文件中获取整个POST主体(没有指定其他字段),那么不要使用files参数,只需将文件直接作为数据发布。然后,您可能也想设置一个Content-Type头,否则将不会设置任何内容。参见Python请求-从文件中POST数据。
有些可能需要通过put请求上传,这与发布数据略有不同。为了形成有效的请求,了解服务器如何期望数据是很重要的。一个常见的混淆来源是当数据不被接受时发送多部分形式的数据。本例使用基本身份验证,并通过put请求更新图像。
url = 'foobar.com/api/image-1'
basic = requests.auth.HTTPBasicAuth('someuser', 'password123')
# Setting the appropriate header is important and will vary based
# on what you upload
headers = {'Content-Type': 'image/png'}
with open('image-1.png', 'rb') as img_1:
r = requests.put(url, auth=basic, data=img_1, headers=headers)
虽然请求库使处理http请求变得容易得多,但它的一些魔力和便利性掩盖了如何创建更微妙的请求。