首页 文章

让JSON对象接受字节或让urlopen输出字符串

提问于
浏览
169

使用Python 3,我从URL请求json文档 .

response = urllib.request.urlopen(request)

response 对象是具有 readreadline 方法的类文件对象 . 通常,可以使用以文本模式打开的文件创建JSON对象 .

obj = json.load(fp)

我想做的是:

obj = json.load(response)

但是这不起作用,因为urlopen以二进制模式返回文件对象 .

解决方法当然是:

str_response = response.read().decode('utf-8')
obj = json.loads(str_response)

但这感觉很糟糕......

有没有更好的方法可以将字节文件对象转换为字符串文件对象?或者我错过了 urlopenjson.load 的任何参数来提供编码?

11 回答

  • 76

    如果您在使用flask微框架时遇到此问题,那么您可以这样做:

    data = json.loads(response.get_data(as_text=True))

    From the docs:"If as_text is set to True the return value will be a decoded unicode string"

  • 1

    我用下面的程序来使用 json.loads()

    import urllib.request
    import json
    endpoint = 'https://maps.googleapis.com/maps/api/directions/json?'
    api_key = 'AIzaSyABbKiwfzv9vLBR_kCuhO7w13Kseu68lr0'
    origin = input('where are you ?').replace(' ','+')
    destination = input('where do u want to go').replace(' ','+')
    nav_request = 'origin={}&destination={}&key={}'.format(origin,destination,api_key)
    request = endpoint + nav_request
    **response = urllib.request.urlopen(request).read().decode('utf-8')
    directions = json.loads(response)**
    print(directions)
    
  • -1

    你的解决方法实际上只是救了我 . 使用Falcon框架处理请求时遇到了很多问题 . 这对我有用 . req是请求表单curl pr httpie

    json.loads(req.stream.read().decode('utf-8'))
    
  • 2

    Python拯救的精彩标准库......

    import codecs
    
    reader = codecs.getreader("utf-8")
    obj = json.load(reader(response))
    

    适用于py2和py3 .

    文件:Python 2Python3

  • 3

    我使用Python 3.4.3和3.5.2以及Django 1.11.3遇到了类似的问题 . 但是,当我升级到Python 3.6.1时,问题就消失了 .

    你可以在这里阅读更多相关信息:https://docs.python.org/3/whatsnew/3.6.html#json

    如果您没有绑定特定版本的Python,请考虑升级到3.6或更高版本 .

  • 18

    刚刚找到这个简单的方法来将HttpResponse内容作为json

    import json
    
    request = RequestFactory() # ignore this, this just like your request object
    
    response = MyView.as_view()(request) # got response as HttpResponse object
    
    response.render() # call this so we could call response.content after
    
    json_response = json.loads(response.content.decode('utf-8'))
    
    print(json_response) # {"your_json_key": "your json value"}
    

    希望对你有所帮助

  • 2

    我认为问题是最好的答案:)

    import json
    from urllib.request import urlopen
    
    response = urlopen("site.com/api/foo/bar").read().decode('utf8')
    obj = json.loads(response)
    
  • 98

    这会将字节数据流式传输到json中 .

    import io
    
    obj = json.load(io.TextIOWrapper(response))
    

    io.TextIOWrapper比编解码器的模块阅读器更受欢迎 . https://www.python.org/dev/peps/pep-0400/

  • 10

    对于其他试图使用 requests 库解决此问题的人:

    import json
    import requests
    
    r = requests.get('http://localhost/index.json')
    r.raise_for_status()
    # works for Python2 and Python3
    json.loads(r.content.decode('utf-8'))
    
  • 66

    HTTP发送字节 . 如果有问题的资源是文本,则通常通过Content-Type HTTP标头或其他机制(RFC,HTML meta http-equiv ,...)指定字符编码 .

    urllib 应该知道如何将字节编码为字符串,但是's too naïve—it'是一个可怕的动力不足和非Pythonic库 .

    Dive Into Python 3提供了有关情况的概述 .

    你的“解决方案”很好 - 虽然感觉不对,但这是正确的方法 .

  • 5

    这个适用于我,我用'request'库 json() 查看requests for humans中的文档

    import requests
    
    url = 'here goes your url'
    
    obj = requests.get(url).json()
    

相关问题