当我想上传文件时,我正在处理需要此请求类型的站点的REST API:
>标题中的“授权”和多部分内容类型
>在表单(正文)中作为二进制字符串文件
>文件键入请求URL
所以我做了这个代码:
import requests
url = 'http://httpbin.org/post'
parameters = {
'format': 'pdf',
}
headers = {
'Content-Type': 'multipart/form-data',
'Accept': 'application/json',
'Authorization' : 'Some authorization code'
}
data = {'file': open('1.pdf', 'rb')}
r = requests.post(url, params=parameters, headers=headers, data=data)
print(r.text)
但似乎请求是丢弃数据:
{
"args": {
"format": "pdf"
},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "application/json",
"Accept-Encoding": "gzip, deflate",
"Authorization": "Some authorization code",
"Connection": "close",
"Content-Length": "30",
"Content-Type": "multipart/form-data",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.18.1"
},
"json": null,
"origin": "x.x.x.x",
"url": "http://httpbin.org/post?format=pdf"
}
它在我删除请求中的’headers’部分时有效:
r = requests.post(url, params=parameters, data=data)
因为回复是:
{
"args": {
"format": "pdf"
},
"data": "",
"files": {},
"form": {
"fax_file": "some samplae texts\n"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Content-Length": "30",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.18.1"
},
"json": null,
"origin": "x.x.x.x",
"url": "http://httpbin.org/post?format=pdf"
}
我也尝试了准备好的请求,结果是一样的.
最佳答案 您正尝试发布文件数据,因此请使用files选项:
r = requests.post(url, params=parameters, files=data, headers=headers)
但是,您实际上不应该设置Content-Type标头;它是在您使用files选项时为您设置的.在这种情况下,标题包括字段边界,真正希望库为您处理这个:
headers = {
'Accept': 'application/json',
'Authorization' : 'Some authorization code'
}
如果您保留Content-Type标头,则必须预先生成内容主体,以便能够向接收服务器提供所需的边界信息.
您也可以尝试删除Accept标头;默认情况下,如果您没有指定该标头,请求将添加Accept:* / *,表示任何内容都是可接受的.
仅使用data参数时,参数将编码为application / x-www-form-urlencoded格式,该格式不支持大型文件数据,并且您的Content-Type标头与实际的POST正文内容不匹配.
请参阅请求文档中的Post a Multipart-Encoded File和Stack Overflow上的application/x-www-form-urlencoded or multipart/form-data?.
演示:
>>> import requests
>>> url = 'http://httpbin.org/post'
>>> parameters = {'format': 'pdf'}
>>> headers = {
... 'Accept': 'application/json',
... 'Authorization' : 'Some authorization code',
... }
>>> data = {'file': open('1.pdf', 'rb')}
>>> r = requests.post(url, params=parameters, files=data, headers=headers)
>>> print(r.text)
{
"args": {
"format": "pdf"
},
"data": "",
"files": {
"file": "<file data as base64>"
},
"form": {},
"headers": {
"Accept": "application/json",
"Accept-Encoding": "gzip, deflate",
"Authorization": "Some authorization code",
"Cache-Control": "max-age=0",
"Connection": "close",
"Content-Length": "374751",
"Content-Type": "multipart/form-data; boundary=d4b84f8bfd464e3f97e3de584d7315fc",
"Host": "httpbin.org",
"O2Gw-Id": "03",
"User-Agent": "python-requests/2.18.4",
"X-Gateway": "wap.london.02.net"
},
"json": null,
"origin": "10.120.6.78, 82.132.221.209",
"url": "http://httpbin.org/post?format=pdf"
}
注意multipart / form-data; border-d4b84f8bfd464e3f97e3de584d7315fc Content-Type标头的值!