Python相当于curls--form:创建包含数据的多部分表单数据post请求;表格「;参数
我正在寻找与此curl命令等效的python:Python相当于curls--form:创建包含数据的多部分表单数据post请求;表格「;参数,python,post,curl,python-requests,multipartform-data,Python,Post,Curl,Python Requests,Multipartform Data,我正在寻找与此curl命令等效的python: curl --referer "https://myreferer" --insecure --form "myparam=1234" https://myurl 这将导致以下请求(取自httpbin.org/post): 如您所见,数据“myparam”以“form”参数的形式传递 我试图通过pythonsrequests模块构建这样一个请求,最终得到了以下代码: import requests payload={'myparam':'123
curl --referer "https://myreferer" --insecure --form "myparam=1234" https://myurl
这将导致以下请求(取自httpbin.org/post):
如您所见,数据“myparam”以“form”参数的形式传递
我试图通过pythonsrequests
模块构建这样一个请求,最终得到了以下代码:
import requests
payload={'myparam':'1234'}
url="http://httpbin.org/post"
headers={'User-Agent': 'Mozilla 5.0','referer':'https://myreferer'}
r = requests.post(url, files=payload, headers=headers,verify=False)
但是请求库将数据放在“files”参数中。因此,生成的请求如下所示:
{
"args": {},
"data": "",
"files": {
"pws": "1234"
},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Content-Length": "143",
"Content-Type": "multipart/form-data; boundary=a878ad29e28d47ffb00e0631319ed0e2",
"Host": "httpbin.org",
"Referer": "https://myreferer",
"User-Agent": "Mozilla 5.0",
"X-Request-Id": "60f5d65e-789a-47fe-bba3-dab88f9bbb65"
...
因此,数据被传递到错误的位置,即在“files”参数中,这使得Apache出现“501 Not Implemented”响应
有人能建议如何在Python中执行这样的请求吗?(我知道我可以将curl作为一个子流程调用,但由于我想执行许多这样的请求,所以我希望有一个纯python的解决方案(希望性能更好)
而且,正如您可能已经注意到的,我还需要接受一个自签名证书并发送一个referer头
如果有人能提出一个简单的方法来解决这个问题,我会很高兴
谢谢
编辑:我已经尝试使用requests.post命令的“data”-param,但这会导致不同的内容类型标题(application/x-www-form-urlencoded)。请注意curl请求的content-type头
编辑:我可能需要的是通过requests.post命令的headers参数简单地发送正确的内容类型header、multipart/form数据。但我还必须计算“边界”——多部分/表单数据头字符串的一部分。我想一定有比手动构造标题和计算边界更简单的方法。对于文件
使用类文件对象
会产生多部分/表单数据
内容类型
让我们准备好通话所需的一切,从“常规”材料开始:
强制请求
使用“多部分/表单数据”的诀窍是至少给它一个类似
反对
buff
现在是我们可以作为files
参数的值传入的类似文件的对象
>>> req = requests.post(url, data=data, headers=headers, stream=True, files=buff)
>>> print req.text
{
"args": {},
"data": "",
"files": {},
"form": {
"myparam": "1234"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Content-Length": "130",
"Content-Type": "multipart/form-data; boundary=0b3bbec1f5c844a1b7377aacfe701f02",
"Host": "httpbin.org",
"Referer": "https://myreferer",
"User-Agent": "Mozilla 5.0",
"X-Request-Id": "988a0467-1c32-45aa-a75c-fba5aa8d632e"
},
"json": null,
"origin": "85.160.45.204",
"url": "http://httpbin.org/post"
}
如果要使用自签名证书与https进行通信,请使用verify=False
:
>>> req = requests.post(url, data=data, headers=headers, stream=True, files=buff, verify=False)
请求的帮助。request
还注意到,verify
的值可能是“CA_BUNDLE path”,因此
可以显式确保服务器正在使用您期望的自签名证书。但是
我从未尝试过这种方法。不幸的是,如果您不想将数据作为文件发送,则必须使用第三方库--。一旦您
pip安装请求toolbelt
,您就可以执行以下操作
from requests_toolbelt import MultipartEncoder
import requests
payload = MultipartEncoder({'myparam': '1234'})
r = requests.post(url, data=payload, headers={'Content-Type': payload.content_type})
当然,您也可以设置其他标题,这只是根据您的需要使用toolbelt的一个简单示例
如果要验证证书,可以将带有完整路径的字符串传递到PEM文件,例如
r = requests.get('https://somesite.com', verify='/Users/mhelwig/certificate.pem')
不,这不是解决方案,因为它会导致不同的内容类型标题。我已经试过了,也许我应该提一下。我将编辑我的帖子。@MichaelHelwig检查我修改的答案。现在它使用
multipart/formdata
内容类型。诀窍是传入一些类似文件的对象。考虑到这是未记录的(我可以保证是无意的)行为,我不会依赖它,因为它很可能会在未来的请求发布中中断。如果它真的坏了,错误报告可能会被认为是无效的。这也是一个有效的工作答案,谢谢!我不知道请求工具带,它似乎对这类东西很有帮助。@sigmavirus24如我的回答所示,你可以用空缓冲区欺骗请求。总之,+1用于指向nice软件包请求_toolbelt
,以及显示验证
与*.pem文件路径的使用。
>>> req = requests.post(url, data=data, headers=headers, stream=True, files=buff, verify=False)
from requests_toolbelt import MultipartEncoder
import requests
payload = MultipartEncoder({'myparam': '1234'})
r = requests.post(url, data=payload, headers={'Content-Type': payload.content_type})
r = requests.get('https://somesite.com', verify='/Users/mhelwig/certificate.pem')