Python post 请求在请求库中引发 400 'Bad Request' 错误,但适用于 cURL

Posted

技术标签:

【中文标题】Python post 请求在请求库中引发 400 \'Bad Request\' 错误,但适用于 cURL【英文标题】:Python post request throwing 400 'Bad Request' error with requests library but works with cURLPython post 请求在请求库中引发 400 'Bad Request' 错误,但适用于 cURL 【发布时间】:2021-12-02 06:22:00 【问题描述】:

我有一个脚本调用 POST 端点但收到 400 错误。同时对应的cURL请求成功。

首先,这里是 cURL:

curl -X 'POST' \
  'http://localhost:8080/api/predict?Key=123testkey' \
  -H 'accept: application/json' \
  -H 'Content-Type: multipart/form-data' \
  -F 'file=@156ac81cde4b3f22faa4055b53867f38.jpg;type=image/jpeg'

并翻译为请求:

import requests

url = 'http://localhost:8080/api/predict?Key=123testkey'

headers = 
    'accept': 'application/json',
    'Content-Type': 'multipart/form-data',


params = 'Key' : '123testkey'

files = 'image': open('156ac81cde4b3f22faa4055b53867f38.jpg', 'rb')

response = requests.post(url, files=files, params=params, headers=headers)

也尝试使用不包含密钥的 URL,因为密钥已在参数中指定:

import requests

url = 'http://localhost:8080/api/predict'

headers = 
    'accept': 'application/json',
    'Content-Type': 'multipart/form-data',


params = 'Key' : '123testkey'

files = 'image': open('156ac81cde4b3f22faa4055b53867f38.jpg', 'rb')

response = requests.post(url, files=files, params=params, headers=headers)

我认为这应该很简单,但无论我尝试什么,我都会收到 400 错误的请求。有什么建议吗?

编辑:也尝试了 'image/jpeg' 而不是 'image' 无济于事。

编辑:不幸的是,用“文件”替换“图像”键也不起作用

编辑:它在邮递员桌面上工作得很好,并生成以下代码。但是,此代码也会引发错误。

邮递员生成的代码:

import requests

url = "http://localhost:8080/api/predict?Key=123test"

payload=
files=[
  ('file',('images19.jpg',open('156ac81cde4b3f22faa4055b53867f38.jpg','rb'),'image/jpeg'))
]
headers = 
  'Accept': 'application/json',
  'Content-Type': 'multipart/form-data'


response = requests.request("POST", url, headers=headers, data=payload, files=files)

print(response.text)

还有来自邮递员之前生成的代码的错误:

"detail":"There was an error parsing the body"

任何帮助弄清楚发生了什么将不胜感激!

【问题讨论】:

files 中,键“image”的值是文件描述符,而不是数据。您需要读取和编码(可能是 Base64)该数据。 尝试使用邮递员 - ***.com/questions/39037049/…。一旦它在那里工作 - 让邮递员为你生成 python 代码。 感谢您的建议,我让它在邮递员中正常工作,但生成的代码抛出以下错误:“detail”:“解析正文时出错”。 【参考方案1】:

您的问题在于您需要使用键“file”而不是“image”添加的变量文件,这是您的 curl 和您的 python 代码之间的区别,还删除了标头,因为当您传递文件参数时,请求集发送文件的正确标题。例如:

import requests

url = 'http://localhost:8080/api/predict?Key=123testkey'

params = 'Key' : '123testkey'

files = 'file': open('156ac81cde4b3f22faa4055b53867f38.jpg', 'rb')

response = requests.post(url, files=files, params=params)

【讨论】:

啊,感谢您指出这一点,这是有道理的...我将密钥更改为“文件”,但奇怪的是仍然收到 400 错误 我认为在标题中也是“接受”,大写“A” 但我认为你不需要传递 header 参数,因为当你传递它检测到的文件是多部分内容类型 哇,一旦我删除了标题,它就可以工作了!好建议,谢谢 很高兴听到,最好的。我用那个改变编辑了答案。

以上是关于Python post 请求在请求库中引发 400 'Bad Request' 错误,但适用于 cURL的主要内容,如果未能解决你的问题,请参考以下文章

Python post请求返回响应400

Python 请求 POST DATA 错误 400 标头名称无效

Postman 400 错误请求

400 bad Request -- 参数不当引发的错误

python requests库中的post详解

get请求400错误,post请求405错误