一尘不染

python请求文件上传

python

我正在执行一个使用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.

仅当文件为空时才会出现。因此,我对如何成功发送文件感到困惑。我知道该文件有效,因为如果我访问此网站并手动填写表格,它将返回一个很好的匹配对象列表,这就是我想要的。我非常感谢所有提示。


阅读 701

收藏
2020-02-22

共1个答案

一尘不染

如果upload_file要作为文件,请使用:

files = {'upload_file': open('file.txt','rb')}
values = {'DB': 'photcat', 'OUT': 'csv', 'SHORT': 'short'}

r = requests.post(url, files=files, data=values)

并且requests将派遣一个多部分表单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"参数。

files如果需要更多控制,则可以使用元组作为映射值,其中包含2到4个元素。第一个元素是文件名,其后是内容,以及可选的content-type标头值和可选的附加标头映射:

files = {'upload_file': ('foobar.txt', open('file.txt','rb'), 'text/x-spam')}

这将设置备用文件名和内容类型,而忽略可选的标题。

如果你要从文件中提取整个POST正文(未指定其他字段),则不要使用files参数,只需将文件直接发布为即可data。然后,你可能还需要设置Content-Type标题,否则将不会设置任何标题。请参阅Python请求-文件中的POST数据。

2020-02-22