在 Python 中发送数据 Curl/Json

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20211990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 19:54:06  来源:igfitidea点击:

Sending data Curl/Json in Python

pythondashing

提问by Spanglish

I`m trying to make those 2 requests in python:

我正在尝试在 python 中发出这 2 个请求:

Request 1:

请求 1:

 curl -X POST -H "Content-Type: application/json" -d '{ "auth_token": "auth1", "widget":   "id1", "title": "Something1",  "text": "Some text", "moreinfo": "Subtitle" }'   serverip

Request 2:

请求 2:

 vsphere_dict = {}
 vsphere_dict['server_name'] = "servername"
 vsphere_dict['api_version'] = apiVersion
 vsphere_dict['guest_count'] = guestCount
 vsphere_dict['guest_on']    = guestOnLen
 vsphere_dict['guest_off']   = guestOffLen

 #Convert output to Json to be sent
 data = json.dumps(vsphere_dict)

 curl -X POST -H "Content-Type: application/json" -d 'data' serverip

Neither of them seems to work. Is there any way I can send them in Python?

它们似乎都不起作用。有什么办法可以用 Python 发送它们吗?

Update:

更新:

The part that I cannot handle is the pass auth and widget. I have tried the following without success:

我无法处理的部分是通行证和小部件。我尝试了以下但没有成功:

import urllib2
import urllib

vsphere_dict = dict(
    server_name="servername",
    api_version="apiVersion",
    guest_count="guestCount",
    guest_on="guestOnLen",
    guest_off="guestOffLen",
)

url = "http://ip:port"

auth = "authid89"
widget = "widgetid1"

# create request object, set url and post data
req = urllib2.Request(auth,url, data=urllib.urlencode(vsphere_dict))
# set header
req.add_header('Content-Type', 'application/json')
# send request
response = urllib2.urlopen(req)**

Resulting in "urllib2.HTTPError: HTTP Error 500: Internal Server Error"

导致“urllib2.HTTPError:HTTP 错误 500:内部服务器错误”

Any ideas how I can pass the auth and widget correctly?

有什么想法可以正确传递身份验证和小部件吗?

UPDATE:

更新:

To see what is different I have started a nc server locally. Here are the results:

为了看看有什么不同,我在本地启动了一个 nc 服务器。结果如下:

Correct curl request using this code:

使用此代码更正 curl 请求:

 curl -X POST -H "Content-Type: application/json" -d '{ "auth_token": "auth", "widget": "widgetid", "title": "Something", "text": "Some text", "moreinfo": "Subtitle" }' http://localhost:8123

sends this which does work:

发送这个确实有效:

 POST / HTTP/1.1
 User-Agent: curl/7.21.0 (i386-redhat-linux-gnu) libcurl/7.21.0 NSS/3.12.10.0 zlib/1.2.5  libidn/1.18 libssh2/1.2.4
 Host: localhst:8123
 Accept: */*
 Content-Type: application/json
 Content-Length: 165

 { "auth_token": "token", "widget": "widgetid", "title": "Something", "text": "Some text", "moreinfo": "Subtitle" }

And request using this code

并使用此代码请求

  import requests
  import simplejson as json

  url = "http://localhost:8123"
  data = {'auth_token': 'auth1', 'widget': 'id1', 'title': 'Something1', 'text': 'Some   text', 'moreinfo': 'Subtitle'}
  headers = {'Content-type': 'application/json'}
  r = requests.post(url, data=json.dumps(data), headers=headers)

sends this which does not work:

发送这个不起作用:

 POST / HTTP/1.1
 Host: localhst:8123
 Content-Length: 108
 Content-type: application/json
 Accept-Encoding: gzip, deflate, compress
 Accept: */*
 User-Agent: python-requests/2.0.1 CPython/2.7.0 Linux/2.6.35.14-106.fc14.i686

 {"text": "Some text", "auth_token": "auth1", "moreinfo": "Subtitle", "widget": "id1",  "title": "Something1"}

回答by Games Brainiac

Well sure, using Python-Requests which is a Python library for sending requests like Curl. You can take a look at the Complicated Post Requestssection.

当然,使用 Python-Requests 是一个 Python 库,用于发送像 Curl 这样的请求。您可以查看复杂的发布请求部分。

Or, if you'd like to use curl inside of Python, you can use pyCurl.

或者,如果您想在 Python 中使用 curl,您可以使用pyCurl

回答by sheh

why not use urllib2?

为什么不使用 urllib2?

import urllib2
import urllib

vsphere_dict = dict(
    server_name="servername",
    api_version=apiVersion,
    guest_count=guestCount,
    guest_on=guestOnLen,
    guest_off=guestOffLen,
)
# create request object, set url and post data
req = urllib2.Request(some_url, data=urllib.urlencode(vsphere_dict))
# set header
req.add_header('Content-Type', 'application/json')
# send request
response = urllib2.urlopen(req)

UPD:

更新:

sorry, by i not understand that is authand widget. Maybe this is also POST data? HTTP Error 500 - can mean that server received not all POST parameters.

对不起,我不明白是authwidget。也许这也是POST数据?HTTP 错误 500 - 可能意味着服务器未收到所有 POST 参数。

回答by Nicola Iarocci

Requestsprovides you with the simplest and yet (very) powerful way to deal with HTTP requests in Python.

Requests为您提供了在 Python 中处理 HTTP 请求的最简单但(非常)强大的方法。

Maybe try something like this:

也许尝试这样的事情:

import requests
import simplejson as json

url = "http://ip:port"
data = {'auth_token': 'auth1', 'widget': 'id1', 'title': 'Something1', 'text': 'Some text', 'moreinfo': 'Subtitle'}
headers = {'Content-type': 'application/json'}
r = requests.post(url, data=json.dumps(data), headers=headers)

If the API requests authentication:

如果 API 请求身份验证:

r = requests.post(url, data=json.dumps(data), headers=headers, auth=('user', 'pass'))

See [Requests auth] for details.

有关详细信息,请参阅 [请求身份验证]。

回答by z3ugma

In the example from the Dashing website, they use:

在 Dashing 网站的示例中,他们使用:

curl -d '{ "auth_token": "YOUR_AUTH_TOKEN", "current": 100 }' http://localhost:3030/widgets/karma

From the cURL man page, maybe you need to post it as form-urlencoded?

从 cURL 手册页,也许您需要将其发布为表单 urlencoded?

-d, --data

-d, --data

(HTTP) Sends the specified data in a POST request to the HTTP server, in the same way that a browser does when a user has filled in an HTML form and presses the submit button. This will cause curl to pass the data to the server using the content-type application/x-www-form-urlencoded. Compare to -F, --form.

(HTTP) 将 POST 请求中的指定数据发送到 HTTP 服务器,就像浏览器在用户填写 HTML 表单并按下提交按钮时所做的那样。这将导致 curl 使用内容类型 application/x-www-form-urlencoded 将数据传递到服务器。与 -F, --form 比较。

-d, --data is the same as --data-ascii. To post data purely binary, you should instead use the --data-binary option. To URL-encode the value of a form field you may use --data-urlencode.

-d, --data 与 --data-ascii 相同。要发布纯二进制数据,您应该改用 --data-binary 选项。要对表单字段的值进行 URL 编码,您可以使用 --data-urlencode。

If any of these options is used more than once on the same command line, the data pieces specified will be merged together with a separating &-symbol. Thus, using '-d name=daniel -d skill=lousy' would generate a post chunk that looks like 'name=daniel&skill=lousy'.

如果在同一命令行上多次使用这些选项中的任何一个,则指定的数据片段将使用分隔符 & 符号合并在一起。因此,使用“-d name=daniel -d Skill=lousy”会生成一个看起来像“name=daniel&skill=lousy”的帖子块。

If you start the data with the letter @, the rest should be a file name to read the data from, or - if you want curl to read the data from stdin. Multiple files can also be specified. Posting data from a file named 'foobar' would thus be done with --data @foobar. When --data is told to read from a file like that, carriage returns and newlines will be stripped out.

如果您以字母@ 开头数据,则其余部分应该是从中读取数据的文件名,或者 - 如果您希望 curl 从 stdin 读取数据。也可以指定多个文件。因此,从名为“foobar”的文件中发布数据将使用 --data @foobar 完成。当 --data 被告知从这样的文件中读取时,将删除回车符和换行符。

You might also want to try python-requests http://requests.readthedocs.org/en/latest/user/quickstart/#more-complicated-post-requests

您可能还想尝试 python-requests http://requests.readthedocs.org/en/latest/user/quickstart/#more-complicated-post-requests

Update: I got it to work

更新:我让它工作了

import requests
import json

payload = {'auth_token': 'YOUR_AUTH_TOKEN', 'title': "pythontest"}
r = requests.post("http://localhost:3030/widgets/welcome", data=json.dumps(payload))

print r.text

You need to post the json like a form.

您需要像表单一样发布json。