183

Python 3では、URLからjsonドキュメントをリクエストしています。

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エンコーディングを提供するためのパラメータがありませんか?

4

12 に答える 12

102

Pythonのすばらしい標準ライブラリが救いの手を差し伸べます…</p>

import codecs

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

py2とpy3の両方で動作します。

ドキュメント:Python 2Python3

于 2014-09-14T01:39:12.060 に答える
80

HTTPはバイトを送信します。問題のリソースがテキストの場合、文字エンコードは通常、Content-Type HTTPヘッダーまたは別のメカニズム(RFC、HTMLなど)のいずれかによって指定されますmeta http-equiv

urllib バイトを文字列にエンコードする方法を知っている必要がありますが、それはあまりにもナイーブです。ひどくパワー​​が不足していて、Pythonicではないライブラリです。

Dive Into Python 3は、状況の概要を示しています。

あなたの「回避策」は問題ありません—それは間違っているように感じますが、それはそれを行う正しい方法です。

于 2011-07-28T17:13:03.753 に答える
67

私はその質問が最良の答えであるとの意見になりました:)

import json
from urllib.request import urlopen

response = urlopen("site.com/api/foo/bar").read().decode('utf8')
obj = json.loads(response)
于 2015-08-27T12:55:57.683 に答える
20

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'))
于 2016-10-13T18:06:42.293 に答える
14

これは私のために働きます、私は人間のための要求json()のドキュメントをチェックすることで「要求」ライブラリを使用しました

import requests

url = 'here goes your url'

obj = requests.get(url).json() 
于 2017-06-13T04:36:26.573 に答える
7

Python 3.4.3&3.5.2とDjango1.11.3を使用して同様の問題が発生しました。ただし、Python 3.6.1にアップグレードすると、問題は解決しました。

詳細については、 https ://docs.python.org/3/whatsnew/3.6.html#jsonをご覧ください。

Pythonの特定のバージョンに縛られていない場合は、3.6以降へのアップグレードを検討してください。

于 2017-07-12T01:19:14.890 に答える
3

フラスコのマイクロフレームワークの使用中にこの問題が発生した場合は、次のようにすることができます。

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

ドキュメントから:「as_textがTrueに設定されている場合、戻り値はデコードされたUnicode文字列になります」

于 2016-12-27T11:17:13.533 に答える
1

あなたの回避策は実際に私を救った。Falconフレームワークを使用してリクエストを処理する際に多くの問題が発生していました。これは私のために働いた。リクエストフォームcurlprhttpieである必要があります

json.loads(req.stream.read().decode('utf-8'))
于 2017-12-09T17:21:37.897 に答える
1

これにより、バイトデータがjsonにストリーミングされます。

import io

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

io.TextIOWrapperは、コーデックのモジュールリーダーよりも優先されます。https://www.python.org/dev/peps/pep-0400/

于 2018-02-28T20:30:36.697 に答える
1

json.loads()Python 3.6以降では、オブジェクトを直接逆シリアル化するために使用できますbytes(エンコードはUTF-8、UTF-16、またはUTF-32である必要があります)。したがって、標準ライブラリのモジュールのみを使用して、次のことができます。

import json
from urllib import request

response = request.urlopen(url).read()
data = json.loads(response)
于 2019-09-25T14:57:03.367 に答える
0

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"}

それがあなたを助けることを願っています

于 2015-12-27T17:20:18.443 に答える
-2

以下のプログラムを使用して使用しました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)
于 2018-02-14T16:24:52.193 に答える