【问题标题】:Sending data Curl/Json in Python在 Python 中发送数据 Curl/Json
【发布时间】:2013-12-11 07:05:57
【问题描述】:

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

请求 1:

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

请求 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

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

更新:

我无法处理的部分是 pass auth 和 widget。我尝试了以下方法但没有成功:

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)**

导致“urllib2.HTTPError: HTTP Error 500: Internal Server Error”

任何想法如何正确传递身份验证和小部件?

更新:

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

使用此代码更正 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

发送此确实有效:

 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" }

并使用此代码请求

  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)

发送这个不起作用:

 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"}

【问题讨论】:

  • 你使用了子进程模块吗?

标签: python dashing


【解决方案1】:

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

不妨试试这样的:

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)

如果 API 请求身份验证:

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

有关详细信息,请参阅 [Requests auth]。

【讨论】:

  • 这看起来很完美,但并没有解决问题。我得到:>>> r.reason '未经授权'
  • 也许您发布到的 API 正在请求身份验证?如果是这样,请参阅authentication,并且不要忘记接受答案:)
  • BasicAuth 示例已添加到答案中。
  • 不工作我仍然得到 401!!。以下是关于 auth.shopify.github.io/dashing/#overview 的一些示例
  • 看起来您需要在请求正文中传递您的身份验证令牌,而不是使用标准身份验证标头(这很奇怪)。删除请求中的 auth= 部分并确保您的 auth_token 是合法的。请接受答案,因为您现在正在处理与“使用 python 发送数据”不同的问题。
【解决方案2】:

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

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

【讨论】:

  • Auth 和 Widget 是我用来对服务器进行身份验证的字段。我需要将它们作为前 2 个参数发送,然后再发送数据。还是没有运气
【解决方案3】:

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

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

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

-d,--数据

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

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

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

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

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

更新:我让它工作了

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

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

【讨论】:

    【解决方案4】:

    为什么不使用 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)
    

    更新:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-21
      • 1970-01-01
      • 2016-07-03
      • 1970-01-01
      • 1970-01-01
      • 2021-07-08
      • 1970-01-01
      • 2014-02-02
      相关资源
      最近更新 更多