如何使用Python请求POST JSON数据?

我需要从客户端向服务器发布JSON。我使用Python 2.7.1和simplejson。客户端使用请求。服务器是CherryPy。我可以从服务器获取硬编码的JSON(代码未显示),但是当我尝试向服务器发布JSON时,我得到“400错误请求”。

这是我的客户端代码:

data = {'sender':   'Alice','receiver': 'Bob','message':  'We did it!'}data_json = simplejson.dumps(data)payload = {'json_payload': data_json}r = requests.post("http://localhost:8080", data=payload)

这是服务器代码。

class Root(object):
def __init__(self, content):self.content = contentprint self.content  # this works
exposed = True
def GET(self):cherrypy.response.headers['Content-Type'] = 'application/json'return simplejson.dumps(self.content)
def POST(self):self.content = simplejson.loads(cherrypy.request.body.read())

有什么想法吗?

1502688 次浏览

原来我缺少标题信息。以下作品:

import requests
url = "http://localhost:8080"data = {'sender': 'Alice', 'receiver': 'Bob', 'message': 'We did it!'}headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}r = requests.post(url, data=json.dumps(data), headers=headers)

从请求版本2.4.2开始,您可以在调用中使用#0参数(接受字典)而不是data=(接受字符串):

>>> import requests>>> r = requests.post('http://httpbin.org/post', json={"key": "value"})>>> r.status_code200>>> r.json(){'args': {},'data': '{"key": "value"}','files': {},'form': {},'headers': {'Accept': '*/*','Accept-Encoding': 'gzip, deflate','Connection': 'close','Content-Length': '16','Content-Type': 'application/json','Host': 'httpbin.org','User-Agent': 'python-requests/2.4.3 CPython/3.4.0','X-Request-Id': 'xx-xx-xx'},'json': {'key': 'value'},'origin': 'x.x.x.x','url': 'http://httpbin.org/post'}

从请求2.4.2(https://pypi.python.org/pypi/requests)开始,支持“json”参数。无需指定“Content-Type”。所以较短的版本:

requests.post('http://httpbin.org/post', json={'test': 'cheers'})

适用于python 3.5+

客户端:

import requestsdata = {'sender':   'Alice','receiver': 'Bob','message':  'We did it!'}r = requests.post("http://localhost:8080", json={'json_payload': data})

服务端:

class Root(object):
def __init__(self, content):self.content = contentprint self.content  # this works
exposed = True
def GET(self):cherrypy.response.headers['Content-Type'] = 'application/json'return simplejson.dumps(self.content)
@cherrypy.tools.json_in()@cherrypy.tools.json_out()def POST(self):self.content = cherrypy.request.jsonreturn {'status': 'success', 'message': 'updated'}

更好的方法是:

url = "http://xxx.xxxx.xx"data = {"cardno": "6248889874650987","systemIdentify": "s08","sourceChannel": 12}resp = requests.post(url, json=data)

您需要使用data/json/files之间的哪个参数取决于名为Content-Type的请求标头(您可以通过浏览器的开发人员工具检查)。

Content-Typeapplication/x-www-form-urlencoded时,使用data=

requests.post(url, data=json_obj)

Content-Typeapplication/json时,您可以使用json=或使用data=并自行设置Content-Type

requests.post(url, json=json_obj)
requests.post(url, data=jsonstr, headers={"Content-Type":"application/json"})

Content-Typemultipart/form-data时,它用于上传文件,因此使用files=

requests.post(url, files=xxxx)

它总是建议我们需要能够读取JSON文件并将对象解析为请求正文。我们不会解析请求中的原始数据,因此以下方法将帮助您解决它。

def POST_request():with open("FILE PATH", "r") as data:JSON_Body = data.read()response = requests.post(url="URL", data=JSON_Body)assert response.status_code == 200

我是这样解决的:

from flask import Flask, requestfrom flask_restful import Resource, Api

req = request.jsonif not req :req = request.formreq['value']
headers = {"charset": "utf-8", "Content-Type": "application/json"}url = 'http://localhost:PORT_NUM/FILE.php'
r = requests.post(url, json=YOUR_JSON_DATA, headers=headers)print(r.text)

使用当前的requests,您可以使用json参数传入任何转储为有效JSON的数据结构,而不仅仅是字典(正如Zeyang Lin的回答错误地声称的那样)。

import requestsr = requests.post('http://httpbin.org/post', json=[1, 2, {"a": 3}])

如果您需要对响应中的元素进行排序,这尤其有用。