質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

解決済

pythonのjson.loadsで文字化けを防ぐ方法に関して

gyungyun545
gyungyun545

総合スコア84

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

3回答

0リアクション

2クリップ

3758閲覧

投稿2019/04/24 01:42

編集2019/04/24 05:13

python3.6にてcgiを作製しております。
クライアント(javascript)からデータを受け取った後までは、日本語がそのまま表示されるのですが、json.loads()にてjsonを読み込ませたところから文字コードが文字化けしてしまいます。
utf-8やshift-jisへの変換を試してみましたがすべて、変換できないといったエラーが返されてしまいます。
どうしても、方法がわからなくて困ってます。
ご教授いただければ幸いです。

※ 下記にソースを簡単に再現しました。
#クライアント

html

<html lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> </head> <body> <form accept-charset="utf-8"> : :

javascript

$.post("test.py", JSON.stringify({text:"ふぇふぇふぇ"}), (res) => { : : });

#サーバー(cgi)

python3

#!/usr/bin/env python3.6 # -*- coding: utf-8 -*- import json import cgi import cgitb import sys, io cgitb.enable() print('Content-type: text/html; charset=UTF-8\r\n') #sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') data = sys.stdin.read() print(data) params = json.loads(data) print(params) exit()

#出力結果
下記のようにdataまでは日本語ですが、json.loads後がバイトコードが表示されてしまいます。

output

{"text":"ふぇふぇふぇ"} {'text':'\udce3\udc81\udcb5\udce3\udc81\udc87\udce3\udc81\udcb5\udce3\udc81\udc87\udce3\udc81\udcb5\udce3\udc81\udc87'}

#試したこと
下記一文を入れてutf-8に変換しようとしたら、unicodeEncodeErrorが返されました。

python3

sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

error

UnicodeEncodeError: 'utf-8' codec can't encode characters in position 9-26: surrogates not allowed args =('utf-8', '{"text":"\udce3\udc81\udcb5\udce3\udc81\udc87\udce3\udc81\udcb5\udce3\udc81\udc87\udce3\udc81\udcb5\udce3\udc81\udc87"}', 9, 27, 'surrogates not allowed') encoding ='utf-8' end =27 object ='{"text":"\udce3\udc81\udcb5\udce3\udc81\udc87\udce3\udc81\udcb5\udce3\udc81\udc87\udce3\udc81\udcb5\udce3\udc81\udc87"}' reason ='surrogates not allowed' start =9 with_traceback =<built-in method with_traceback of UnicodeEncodeError object>

#補足20190424 13:21
環境面の補足です。
python3のデフォルトのencodingですが、環境で実行した場合とcgiから実行した場合で値がことなりました。サーバーでインタプリタで実行した際は「UTF-8」でしたが、
cgiから実行した場合は、stdin/stdoutともに、「ANSI_X3.4-1968」でした。

Bash

$ locale LANG=ja_JP.UTF-8 LC_CTYPE="ja_JP.UTF-8" LC_NUMERIC="ja_JP.UTF-8" LC_TIME="ja_JP.UTF-8" LC_COLLATE="ja_JP.UTF-8" LC_MONETARY="ja_JP.UTF-8" LC_MESSAGES="ja_JP.UTF-8" LC_PAPER="ja_JP.UTF-8" LC_NAME="ja_JP.UTF-8" LC_ADDRESS="ja_JP.UTF-8" LC_TELEPHONE="ja_JP.UTF-8" LC_MEASUREMENT="ja_JP.UTF-8" LC_IDENTIFICATION="ja_JP.UTF-8" LC_ALL=

#補足20190424 13:54
皆様のおかげでjsonファイルにunicodeを出力するところまで行けました。
unicodeであれば読み込むときに変換ができるので、なんとか行けそうです。
ただ、ファイルにコードではなくちゃんと日本語で表記されるようにするにはどうすればよいでしょうか?
dumpsでensure_ascii=Falseにしても、どうしてもunicodeで出力されてしまいます。

python3

#!/usr/bin/env python3.6 # -*- coding: utf-8 -*- import json import cgi import cgitb import sys, io cgitb.enable() sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8') sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8') print('Content-type: text/html; charset=UTF-8\r\n') data = sys.stdin.buffer.read() print(data) params = json.loads(data) print(params) with open("sample", mode="w", encode="utf-8") as f: json.dumps(params, f, indent=2, ensure_ascii=False) exit()

output

{"text": "\u3042"} {"text": "あ"}

ファイルに{"text": "あ"}と出力したい。

sample

{"text": "\u3042"}

#補足20190424 14:11
解決しました。
ソースを何度も修正する際にミスが有ったようです。
具体的には、同じコードを複数書いてexit()で実行されないようにしていたのですが、
ensure_ascii=Falseを追加する場所を間違えてました。
ずっとこの課題に取り組み、疲れが溜まっていたのが原因です。
本当に解決してよかったです。しばらく休みます。

下に最終的にうまく行ったコードを載せます。

python3

#!/usr/bin/env python3.6 # -*- coding: utf-8 -*- import json import cgi import cgitb import sys, io cgitb.enable() sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8') sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8') print('Content-type: text/html; charset=UTF-8\r\n') data = sys.stdin.buffer.read() print(data) params = json.loads(data.decode()) print(params) with open("sample", mode="w", encoding="utf-8") as f: json.dumps(params, f, indent=2, ensure_ascii=False) exit()

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。