python - 将 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(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'])

进入:

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

这次我有 400:错误请求。但是带有 curl 的 bash 代码有效。您知道我应该在 Python 代码中修复什么吗?

最佳答案

PycURL 是用 C 语言编写的 libcurl 库的包装器,因此它的 Python API 可能有点令人费解。由于有些人提倡使用 python 请求,我只想指出它不是完美的替代品。对我来说,它没有 DNS 解析超时是一个大问题。我还发现它在我的 Raspberry Pi 上慢得多。这种比较可能是相关的: Python Requests vs PyCurl Performance

所以这里有一些不能回避 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()

libcurl curleasy setopts documentation 中还有一些更有趣的功能值得一试

关于python - 将 POST 请求 curl 到 pycurl 代码中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31826814/

相关文章:

python - 如何从较小的快照创建具有较大磁盘的计算实例?

Python REST API 发布列表

javascript - 我的 JavaScript Post 和 Get 函数与 python 服务器发生故障

web-services - SQL Server 2008 数据库能否在两个不同的端点中同时支持 REST 和 SOAP Web 服务?

php - 使用 php 将 POST 数据转储到 XML

web-services - 如何从 Web 服务请求中获取原始数据?

python - Sklearn.LogisticRegression 是否添加一列 1?

Python Turtle - 无法为 turtle 设置边界?

python - 将sql结果转换为list python

web-services - Web 服务客户端证书/身份验证最佳实践的解决方案