Python 将POST请求卷曲为pycurl代码

Python 将POST请求卷曲为pycurl代码,python,rest,post,curl,pycurl,Python,Rest,Post,Curl,Pycurl,我正在尝试将以下curl请求转换为pycurl: curl -v -H Accept:application/json \ -H Content-Type:application/json \ -d "{ name: 'abc', path: 'def', target: [ 'ghi' ] }" \ -X POST http://some-url 我有以下python代码: import pycurl, json c = pycurl.Curl() c.setopt

我正在尝试将以下curl请求转换为pycurl:

curl -v
-H Accept:application/json \
-H Content-Type:application/json \
-d "{
    name: 'abc',
    path: 'def',
    target: [ 'ghi' ]
}" \
-X POST http://some-url
我有以下python代码:

import pycurl, json

c = pycurl.Curl()
c.setopt(pycurl.URL, 'http://some-url')
c.setopt(pycurl.HTTPHEADER, ['Accept: application/json'])
data = json.dumps({"name": "abc", "path": "def", "target": "ghi"})
c.setopt(pycurl.POST, 1)
c.setopt(pycurl.POSTFIELDS, data)
c.setopt(pycurl.VERBOSE, 1)
c.perform()
print curl_agent.getinfo(pycurl.RESPONSE_CODE)
c.close()
执行此操作时出现错误415:不支持的媒体类型,因此我已更改:

c.setopt(pycurl.HTTPHEADER, ['Accept: application/json'])
进入:


这一次我有400:错误的要求。但是带有curl的bash代码可以工作。你知道我应该在python代码中修复什么吗?

在bash示例中,属性
target
是一个数组,在python示例中是一个字符串

试试这个:

data = json.dumps({"name": "abc", "path": "def", "target": ["ghi"]})
我还强烈建议您查看具有更好API的库:

import requests
data = {"name": "abc", "path": "def", "target": ["ghi"]}
response = requests.post('http://some-url', json=data)
print response.status_code

使用请求库更简单。()

我为您的原始curl自定义头附加python代码

import json
import requests

url = 'http://some-url'
headers = {'Content-Type': "application/json; charset=xxxe", 'Accept': "application/json"}
data = {"name": "abc", "path": "def", "target":  ["ghi"]}
res = requests.post(url, json=data, headers=headers)
print (res.status_code)
print (res.raise_for_status())

我知道这已经超过一年了,但请尝试删除标题值中的空白

c.setopt(pycurl.HTTPHEADER, ['Accept:application/json'])

我也更喜欢使用requests模块,因为API/方法干净且易于使用。

我也有类似的问题,我使用了您的代码示例,但更新了
httpheader
部分,如下所示:

c.setopt(pycurl.HTTPHEADER, ['Content-Type:application/json'])

PycURL是用C语言编写的libcurl库的包装器,因此其pythonapi可能有点令人费解。因为有些人提倡使用python请求,所以我只想指出,它并不是一个完美的替代品。对我来说,它缺少DNS解析超时是一个破坏交易的因素。我还发现在我的树莓皮上速度要慢得多。这种比较可能是相关的:

所以这里有一些东西并没有回避OP的问题:

import pycurl
import json
from cStringIO import StringIO

curl = pycurl.Curl()
curl.setopt(pycurl.URL, 'http://some-url')
curl.setopt(pycurl.HTTPHEADER, ['Accept: application/json',
                                'Content-Type: application/json'])
curl.setopt(pycurl.POST, 1)

# If you want to set a total timeout, say, 3 seconds
curl.setopt(pycurl.TIMEOUT_MS, 3000)

## depending on whether you want to print details on stdout, uncomment either
# curl.setopt(pycurl.VERBOSE, 1) # to print entire request flow
## or
# curl.setopt(pycurl.WRITEFUNCTION, lambda x: None) # to keep stdout clean

# preparing body the way pycurl.READDATA wants it
# NOTE: you may reuse curl object setup at this point
#  if sending POST repeatedly to the url. It will reuse
#  the connection.
body_as_dict = {"name": "abc", "path": "def", "target": "ghi"}
body_as_json_string = json.dumps(body_as_dict) # dict to json
body_as_file_object = StringIO(body_as_json_string)

# prepare and send. See also: pycurl.READFUNCTION to pass function instead
curl.setopt(pycurl.READDATA, body_as_file_object) 
curl.setopt(pycurl.POSTFIELDSIZE, len(body_as_json_string))
curl.perform()

# you may want to check HTTP response code, e.g.
status_code = curl.getinfo(pycurl.RESPONSE_CODE)
if status_code != 200:
    print "Aww Snap :( Server returned HTTP status code {}".format(status_code)

# don't forget to release connection when finished
curl.close()

有一些更有趣的功能值得在

中查看。请求库在许多方面被破坏,对于任何严格或稍微不一致的服务器都是无用的。有些请求可以很好地使用curl,但在使用请求库时由于各种不必要的清理而被拒绝。@Nimrod感谢您的评论。我没有意识到这一点,我自己也从未遇到过任何请求问题,但我有兴趣了解更多关于您描述的问题的信息。你能告诉我更多的信息吗?不,我强烈反对,python请求并不总是冠军。如果你想上传一个可读流的文件,那么pycurl的FORM_文件就可以了。请解释为什么StringIO和cStringIO模块不存在会更好。相反导入io模块,分别对文本和数据使用io.StringIO或io.BytesIO。可能有用:
从io导入StringIO
@MaxBase有趣,但cStringIO有自己的位置,因为它是用C编写的,不同于io.StringIO或StringIO.StringIO,可以看出它在PycURL的常用用法中的性能如何编写性能更高的代码,这样我想读者会觉得cStringIO是一个更好的赞美。非常感谢,经过几天的调查,这对我帮助很大
import pycurl
import json
from cStringIO import StringIO

curl = pycurl.Curl()
curl.setopt(pycurl.URL, 'http://some-url')
curl.setopt(pycurl.HTTPHEADER, ['Accept: application/json',
                                'Content-Type: application/json'])
curl.setopt(pycurl.POST, 1)

# If you want to set a total timeout, say, 3 seconds
curl.setopt(pycurl.TIMEOUT_MS, 3000)

## depending on whether you want to print details on stdout, uncomment either
# curl.setopt(pycurl.VERBOSE, 1) # to print entire request flow
## or
# curl.setopt(pycurl.WRITEFUNCTION, lambda x: None) # to keep stdout clean

# preparing body the way pycurl.READDATA wants it
# NOTE: you may reuse curl object setup at this point
#  if sending POST repeatedly to the url. It will reuse
#  the connection.
body_as_dict = {"name": "abc", "path": "def", "target": "ghi"}
body_as_json_string = json.dumps(body_as_dict) # dict to json
body_as_file_object = StringIO(body_as_json_string)

# prepare and send. See also: pycurl.READFUNCTION to pass function instead
curl.setopt(pycurl.READDATA, body_as_file_object) 
curl.setopt(pycurl.POSTFIELDSIZE, len(body_as_json_string))
curl.perform()

# you may want to check HTTP response code, e.g.
status_code = curl.getinfo(pycurl.RESPONSE_CODE)
if status_code != 200:
    print "Aww Snap :( Server returned HTTP status code {}".format(status_code)

# don't forget to release connection when finished
curl.close()