TypeError: объект JSON должен быть str, а не "байтами" - Python - fixer.io

У меня есть этот код:

from flask import Flask, flash, redirect, render_template, request, session, abort
import os
import json
from urllib.request import urlopen

tmpl_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates')
app = Flask(__name__, template_folder=tmpl_dir)

def getExchangeRates():
    rates = []
    response = urlopen('https://data.fixer.io/api/latest?access_key=my_key')
    data = response.read()
    rdata = json.loads(data, parse_float=float)

    rates.append( rdata['rates']['USD'] )
    rates.append( rdata['rates']['GBP'] )
    rates.append( rdata['rates']['HKD'] )
    rates.append( rdata['rates']['AUD'] )
    return rates

@app.route("/")
def index():
    rates = getExchangeRates()
    return render_template('test.html',**locals())      

@app.route("/hello")
def hello():
    return "Hello World!"

Но это бросает меня в это:

Traceback (most recent call last):
File "/home/kristian/.virtualenvs/usio_flask/lib/python3.4/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/home/kristian/.virtualenvs/usio_flask/lib/python3.4/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/kristian/.virtualenvs/usio_flask/lib/python3.4/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/kristian/.virtualenvs/usio_flask/lib/python3.4/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/home/kristian/.virtualenvs/usio_flask/lib/python3.4/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/home/kristian/.virtualenvs/usio_flask/lib/python3.4/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "app/app.py", line 23, in index
rates = getExchangeRates()
File "app/app.py", line 13, in getExchangeRates
rdata = json.loads(data, parse_float=float)
File "/usr/lib/python3.4/json/__init__.py", line 312, in loads
s.__class__.__name__))
TypeError: the JSON object must be str, not 'bytes'

Это оскорбительная строка:

rdata = json.loads(data, parse_float=float)

Я просто пытаюсь получить некоторые оценки от fixer.io API, есть идеи?

if name == "main": app.run ()

1 ответ

Решение

[Python 3.5]: JSON. загружает (s, *, encoding = None, cls = None, object_hook = None, parse_float = None, parse_int = None, parse_constant = None, object_pairs_hook = None, ** kw) состояния:

Десериализовать s (экземпляр str, содержащий документ JSON) в объект Python, используя эту таблицу преобразования.

urllib.request.urlopen возвращает http.client.HTTPResponse объект.

Согласно [Python 3.5]: HTTPResponse. читать ([amt]):

Читает и возвращает тело ответа или до следующих байтов.

Итак, чтобы сделать это, вы должны преобразовать байты в стр
(через [Python 3.5]: bytes. decode (encoding = "utf-8", errors = "strict")):

rdata = json.loads(data.decode(), parse_float=float)

Примечание:

  • Начиная с Python 3. 6, json.loads способен также обрабатывать байты

Что касается вашей другой ошибки, я помню (как я когда-то работал с Flask), что Response объекты имели только json() метод, если код состояния HTTP был 200 (ОК). Но я не уверен, что это тот же объект, о котором мы говорим, так как я использовал модуль запросов.

Другие вопросы по тегам