在 Python 中检索 JSON 以响应 POST

Posted

技术标签:

【中文标题】在 Python 中检索 JSON 以响应 POST【英文标题】:Retrieving JSON in Python in response to POST 【发布时间】:2018-09-01 01:29:49 【问题描述】:

我正在尝试从服务器获取 JSON 以在 Python 代码中使用它。出于测试目的,我通过curl 做了POST

$ curl -u trial:trial -H "Content-Type: application/json"
-X POST -d '"BP_TSM":"22"' http://some-host --trace-ascii -

我的 Java 代码似乎可以正确处理创建 JSON 作为响应。请看curl命令的结果:

 == Info: About to connect() to localhost port 8080 (#0)
== Info:   Trying ::1...
== Info: Connected to localhost (::1) port 8080 (#0)
== Info: Server auth using Basic with user 'trial'
=> Send header, 224 bytes (0xe0)
0000: POST /get/auth HTT
0040: P/1.1
0047: Authorization: Basic dHJpYWw6dHJpYWw=
006e: User-Agent: curl/7.29.0
0087: Host: localhost:8080
009d: Accept: */*
00aa: Content-Type: application/json
00ca: Content-Length: 15
00de: 
=> Send data, 15 bytes (0xf)
0000: "BP_TSM":"22"
== Info: upload completely sent off: 15 out of 15 bytes
<= Recv header, 23 bytes (0x17)
0000: HTTP/1.1 202 Accepted
<= Recv header, 34 bytes (0x22)
0000: Server: Payara Micro #badassfish
<= Recv header, 32 bytes (0x20)
0000: Content-Type: application/json
<= Recv header, 37 bytes (0x25)
0000: Date: Thu, 22 Mar 2018 14:30:43 GMT
<= Recv header, 21 bytes (0x15)
0000: Content-Length: 108
<= Recv header, 29 bytes (0x1d)
0000: X-Frame-Options: SAMEORIGIN
<= Recv header, 2 bytes (0x2)
0000: 
<= Recv data, 108 bytes (0x6c)
0000: "title":"Free Music Archive - Albums","message":"","total":"112
0040: 59","total_pages":2252,"page":1,"limit":"5"
"title":"Free Music Archive - Albums","message":"","total":"11259","total_pages

":2252,"page":1,"limit":"5"== Info: Connection #0 to host localhost left intact

现在我希望 Python 脚本能够接收到与 curl 相同的消息。我编写了以下 Python 代码(注意我不是 Python 开发人员):

import pickle
import requests
import codecs
import json
from requests.auth import HTTPBasicAuth
from random import randint
req = requests.get('server/get/auth', auth=HTTPBasicAuth('trial', 'trial'))
return pickle.dumps(req)

不幸的是,当执行return pickle.dumps(req) 命令时,我收到错误消息'unicode' object has no attribute 'copy'。我也尝试过使用return json.dumps(req),但这次我又遇到了一个错误:

Traceback (most recent call last):
  File "/tmp/tmp8DfLJ7/usercode.py", line 16, in the_function
    return json.dumps(req)
  File "/usr/lib64/python2.7/json/__init__.py", line 244, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib64/python2.7/json/encoder.py", line 207, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib64/python2.7/json/encoder.py", line 270, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib64/python2.7/json/encoder.py", line 184, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <Response [405]> is not JSON serializable

我的 Python 代码是否有错误,或者是我的 Java 服务器返回不正确的 JSON 造成的?

【问题讨论】:

您正在尝试转储一个响应对象。尝试返回 req.json() 或调用 json.loads(req.text) 【参考方案1】:

您的 Python 代码中有许多错误。

您正在使用request.get 发布。请改用request.post。 您没有将BP_TSM json 字符串传递到您的请求中。在您的request.post 中使用data=。 您没有模拟 -H 切换到 curl。在您的request.post 中使用headers=。 您无缘无故地使用pickle。不要那样做。 当您不在函数中时,您正在使用return 语句。不要那样做。如果要打印到标准输出,请改用print()sys.stdout.write()。 如果您确实想使用 JSON 中返回的变量(而不是简单地打印到标准输出),您应该调用 req.json()

这是解决问题的代码版本。

import requests
import json
import sys
from requests.auth import HTTPBasicAuth

data = '"BP_TSM": "22"'                       # curl -d
headers = 'content-type': 'application/json'  # curl -H
auth = HTTPBasicAuth('trial', 'trial')          # curl -u

req = requests.post(                            # curl -X POST
    'http://httpbin.org/post',
    auth=auth,
    data=data,
    headers=headers)
sys.stdout.write(req.text)         # Display JSON on stdout
returned_data = req.json()
my_ip = returned_data["origin"]    # Query value from JSON
print("My public IP is", my_ip)

【讨论】:

感谢一百万!我在很多地方寻找错误,但它在 You are using request.get to POST.(以及许多其他地方)。 不客气。另请注意我的回答中使用了httpbin.org。它是单独测试 Web 客户端代码或在 Stack Overflow 帖子中使用的绝佳资源。【参考方案2】:

您正在尝试转储 Response 对象。

尝试返回req.json() 或致电json.loads(req.text)

【讨论】:

【参考方案3】:

为了加载 Json 字符串,您需要使用 json.loads(req.text)

您还必须确保 req 字符串是有效的 json。

例如

'"FOO":"BAR"'

【讨论】:

【参考方案4】:

您可以使用requests.json() 方法将json响应作为dict获取

req = requests.get('http://yourdomain.com/your/path', auth=HTTPBasicAuth('trial', 'trial'))
mydict = req.json()

【讨论】:

以上是关于在 Python 中检索 JSON 以响应 POST的主要内容,如果未能解决你的问题,请参考以下文章

运行 CGI Python Javascript 以检索 JSON 对象

iOS 检索 Web 响应数据后如何从 JSON 中检索值

使用 AJAX Jquery 以 JSON 格式显示检索到的图像 URL

在python中使用for循环时出现JSONDecodeError [重复]

Python - 从 JSON 响应中提取数据(使用 TomTom api)

从远程响应中检索 JSON 数据