В Python 3 я запрашиваю документ json с URL.
response = urllib.request.urlopen(request)
response
Объект представляет собой файл-подобный объект с read
и readline
методы. Обычно объект JSON можно создать с помощью файла, открытого в текстовом режиме.
obj = json.load(fp)
Что я хотел бы сделать, это:
obj = json.load(response)
Это, однако, не работает, так как urlopen возвращает объект файла в двоичном режиме.
Обойти это, конечно,
str_response = response.read().decode('utf-8')
obj = json.loads(str_response)
но это плохо ...
Есть ли лучший способ, которым я могу преобразовать объект файла байтов в объект файла строки? Или я пропускаю какие-либо параметры для urlopen
или json.load
для кодирования?
Ответы:
HTTP отправляет байты. Если рассматриваемым ресурсом является текст, кодировка символов обычно указывается либо с помощью HTTP-заголовка Content-Type, либо с помощью другого механизма (RFC, HTML
meta http-equiv
, ...).urllib
Я должен знать, как кодировать байты в строку, но это слишком наивно - это ужасно слабая и непитоновская библиотека.Dive Into Python 3 предоставляет обзор ситуации.
Ваш «обходной путь» хорош - хотя он и кажется неправильным, это правильный способ сделать это.
источник
urlopen
должен иметь возможность декодировать байты сам, так как он знает кодировку. Во всяком случае, я опубликовал решение стандартной библиотеки Python в качестве ответа - вы можете сделать потоковое декодирование байтов с помощьюcodecs
модуля.Прекрасная стандартная библиотека Python для спасения ...
Работает как с py2, так и с py3.
Документы: Python 2 , Python3
источник
python 3.4.3
не знаю почему? Ошибка былаTypeError: the JSON object must be str, not 'StreamReader'
json.loads()
вместоjson.load()
?response.headers.get_content_charset()
. Возвращает,None
если кодировка отсутствует и не существует на python2.Я пришел к мнению, что вопрос является лучшим ответом :)
источник
Для тех, кто пытается решить эту проблему с помощью
requests
библиотеки:источник
requests
: вы можете просто сделатьr.json()
json.loads
. Все, что вам нужно сделать, -r.json()
и вы уже загрузили свой объект JSON в dict.*** UnicodeEncodeError: 'ascii' codec can't encode characters in position 264-265: ordinal not in range(128)
Этот работает для меня, я использовал библиотеку 'request' с
json()
проверкой документации в запросах для людейисточник
Я столкнулся с подобными проблемами, используя 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 или более поздней.
источник
Если вы столкнулись с этой проблемой при использовании микрорамки с колбой, вы можете просто:
data = json.loads(response.get_data(as_text=True))
Из документов : «Если as_text установлен в True, возвращаемое значение будет декодированной строкой Юникода»
источник
Твой обходной путь фактически спас меня. У меня было много проблем с обработкой запроса с использованием платформы Falcon. Это сработало для меня. требуется форма запроса curl pr httpie
источник
Это будет поток данных байта в JSON.
io.TextIOWrapper предпочтительнее модуля чтения кодека. https://www.python.org/dev/peps/pep-0400/
источник
json.loads(bytes_obj.decode())
.Только что нашел этот простой способ сделать содержимое HttpResponse как json
Надеюсь, что это поможет вам
источник
Начиная с Python 3.6, вы можете использовать
json.loads()
для десериализацииbytes
объекта напрямую (кодировка должна быть UTF-8, UTF-16 или UTF-32). Итак, используя только модули из стандартной библиотеки, вы можете сделать:источник
Я использовал ниже программу для использования
json.loads()
источник