Dengan Python 3 saya meminta dokumen json dari URL.
response = urllib.request.urlopen(request)
The response
objek adalah objek file seperti dengan read
dan readline
metode. Biasanya objek JSON dapat dibuat dengan file yang dibuka dalam mode teks.
obj = json.load(fp)
Yang ingin saya lakukan adalah:
obj = json.load(response)
Namun ini tidak berfungsi karena urlopen mengembalikan objek file dalam mode biner.
Pekerjaan di sekitar tentu saja:
str_response = response.read().decode('utf-8')
obj = json.loads(str_response)
tapi ini terasa buruk ...
Apakah ada cara yang lebih baik untuk mengubah objek file byte menjadi objek file string? Atau apakah saya kehilangan parameter untuk salah satu urlopen
atau json.load
memberikan pengkodean?
Jawaban:
HTTP mengirim byte. Jika sumber daya yang dimaksud adalah teks, pengkodean karakter biasanya ditentukan, baik dengan header HTTP Content-Type atau dengan mekanisme lain (RFC, HTML
meta http-equiv
, ...).urllib
harus tahu cara menyandikan byte ke string, tapi terlalu naif — itu perpustakaan yang sangat kurang bertenaga dan tidak Pythonic.Dive Into Python 3 memberikan ikhtisar tentang situasi tersebut.
"Kerjakan" Anda baik-baik saja — meskipun rasanya salah, itu cara yang tepat untuk melakukannya.
sumber
urlopen
seharusnya dapat men-decode byte itu sendiri karena ia tahu encoding. Bagaimanapun, saya telah memposting solusi pustaka standar Python sebagai jawaban - Anda dapat melakukan streaming decoding byte menggunakancodecs
modul.Perpustakaan standar Python yang luar biasa untuk menyelamatkan ...
Bekerja dengan kedua py2 dan py3.
Docs: Python 2 , Python3
sumber
python 3.4.3
tidak yakin mengapa? Kesalahannya adalahTypeError: the JSON object must be str, not 'StreamReader'
json.loads()
sebagai gantijson.load()
?response.headers.get_content_charset()
. KembaliNone
jika tidak ada penyandian, dan tidak ada di python2.Saya berpendapat bahwa pertanyaannya adalah jawaban terbaik :)
sumber
Untuk siapa pun yang mencoba menyelesaikan ini menggunakan
requests
perpustakaan:sumber
requests
: Anda dapat melakukannyar.json()
json.loads
. Yang harus Anda lakukan adalahr.json()
dan objek JSON Anda sudah dimuat ke dalam dict.*** UnicodeEncodeError: 'ascii' codec can't encode characters in position 264-265: ordinal not in range(128)
Yang ini berfungsi untuk saya, saya menggunakan perpustakaan 'permintaan' dengan
json()
memeriksa dokumen dalam permintaan untuk manusiasumber
Saya mengalami masalah yang sama menggunakan Python 3.4.3 & 3.5.2 dan Django 1.11.3. Namun, ketika saya memutakhirkan ke Python 3.6.1 masalah hilang.
Anda dapat membaca lebih lanjut tentang ini di sini: https://docs.python.org/3/whatsnew/3.6.html#json
Jika Anda tidak terikat dengan versi Python tertentu, cukup pertimbangkan untuk meningkatkan ke 3.6 atau yang lebih baru.
sumber
Jika Anda mengalami masalah ini saat menggunakan mikroframework flask, maka Anda bisa melakukannya:
data = json.loads(response.get_data(as_text=True))
Dari dokumen : "Jika as_text disetel ke True nilai kembalian akan menjadi string unicode yang didekodekan"
sumber
Solusi Anda sebenarnya baru saja menyelamatkan saya. Saya mengalami banyak masalah saat memproses permintaan menggunakan kerangka kerja Falcon. Ini berhasil untuk saya. req menjadi bentuk permintaan ikal pr httpie
sumber
Ini akan mengalirkan data byte ke json.
io.TextIOWrapper lebih disukai daripada pembaca modul codec. https://www.python.org/dev/peps/pep-0400/
sumber
json.loads(bytes_obj.decode())
.Baru saja menemukan metode sederhana ini untuk menjadikan konten HttpResponse sebagai json
Semoga itu bisa membantu Anda
sumber
Pada Python 3.6, Anda bisa menggunakan
json.loads()
deserializebytes
objek secara langsung (pengkodean harus UTF-8, UTF-16 atau UTF-32). Jadi, hanya menggunakan modul dari perpustakaan standar, Anda dapat melakukan:sumber
Saya menggunakan program di bawah ini untuk menggunakan
json.loads()
sumber