使用来自服务器的 GET 请求返回 JSON

mon*_*boi 3 python json python-requests

我有一个简单的服务器从这里,当GET函数被调用时,我想它在下面的相关代码段返回一个JSON文件,如下显示:

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import json

class S(BaseHTTPRequestHandler):
    def _set_headers(self):
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()

    def do_GET(self):
        self._set_headers()
        with open('test.json') as data_file:    
            data = json.load(data_file)
        self.wfile.write(data)
Run Code Online (Sandbox Code Playgroud)

我的json文件:

{"foo": "bar", "boo": "far"}
Run Code Online (Sandbox Code Playgroud)

请求文件 (client.py) 的应用程序:

import requests
import json

r = requests.get('http://localhost:8080')
print r.json()
Run Code Online (Sandbox Code Playgroud)

但是,当尝试运行 client.py 时,出现以下错误:

ValueError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
Run Code Online (Sandbox Code Playgroud)

我是否在 do_GET 函数中正确加载了 test.json 文件?

谢谢你的帮助 :)

zwe*_*wer 5

让我们把答案做得更好一点:)

整个问题是您test.json在服务器中解析,然后将它的字符串表示打印到您的客户端。考虑一个简单的 JSON,如:

{"foo": "bar", "baz": "far"}

当您将其加载并解析为 JSON,然后打印它时,您将获得dict解析为Python 的字符串表示形式,虽然非常相似,但不再是 JSON:

import json

data = '{"foo": "bar", "baz": "far"}'  # we'll use a string instead of a file for testing
parsed = json.loads(data)
print(parsed)  # equivalent to printing `str(parsed)`
Run Code Online (Sandbox Code Playgroud)

这将产生(在 Python 2.x 上,在 Python 3.x 上没有 unicode 标记,但其余部分相同):

{u'foo': u'bar', u'baz': u'far'}

这就是您的数据从服务器发送的方式 - 作为 Python 的字符串表示形式dict。请注意,例如,那些u表示 unicode 字符串的前缀?这些是罪魁祸首(在这种情况下)。

现在,如果您要重新加载它并尝试将其解析为 JSON:

import json 

data = "{u'foo': u'bar', u'baz': u'far'}"
parsed = json.loads(data)
Run Code Online (Sandbox Code Playgroud)

你会得到你的ValueError: Expecting property name: line 1 column 2 (char 1)错误。

为避免这种情况,如果要将 JSON 发送给客户端,请不要解析它,很简单:

with open('test.json') as data_file:
    self.wfile.write(data_file.read())
Run Code Online (Sandbox Code Playgroud)

应该足够了。如果您需要对 JSON 进行一些预处理,则需要在发送之前将其序列化回 JSON,例如:

with open('test.json') as data_file:    
    data = json.load(data_file)
    data["boo"] = "baz"
    self.wfile.write(json.dumps(data))
Run Code Online (Sandbox Code Playgroud)