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

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

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

Unicodeはエンコーディングの標準規格です。1つの文字コード体系で多国語の表現を可能にすることを目指して作られています。

エスケープ処理

エスケープ処理とは、一連の文字や一文字に対して、一定の規則に従って別の意味を適用する処理過程です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

2555閲覧

Pythonで辞書型の値にunicodeエスケープ値を格納したい

aoiro27

総合スコア14

Unicode

Unicodeはエンコーディングの標準規格です。1つの文字コード体系で多国語の表現を可能にすることを目指して作られています。

エスケープ処理

エスケープ処理とは、一連の文字や一文字に対して、一定の規則に従って別の意味を適用する処理過程です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1グッド

1クリップ

投稿2020/07/29 04:48

最終的に辞書型に以下のようなユニコードエスケープされた値を格納したいと思っています。

dic1 = { "data": "\u307b\u3052" }

ここで、ユニコードエスケープされた文字列を得るために以下のような処理を書くと、

dic1 = {  "data" : "ほげ".encode("unicode-escape").decode('utf-8') } dic1

dic1の出力としては以下のようにバックスラッシュがエスケープされた値になってしまいます。

{'data': '\u307b\u3052'}

一番上ような直接ユニコードエスケープされた文字列を記載すれば正常に動作しますが、
文字列からユニコードエスケープさせた値を取得して辞書型の値とするにはどういう記載としたら良いでしょうか?

DrqYuto👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2020/07/29 05:03 編集

コード上の2つの辞書「{"data": "\u307b\u3052"}」と「{'data': 'ほげ'}」は書き方が異なるだけで辞書型のデータとしては等価です。 たとえば「n=12」と「n=0x0C」もコード上の表現は異なりますが等価です。 この辞書の'data'値から「\u307b\u3052」という文字列を得たいという質問でしょうか?
aoiro27

2020/07/29 05:09

APIのリクエストbodyとしてこのjsonを投げたいのですが、 APIの仕様としてユニコードエスケープされた文字列化する必要があります。 requests.post(url, headers=headers, json=dic1) と投げる時に、{"data": "\u307b\u3052"}という書式としたいというのがやりたいこととなります。 これが今の状態だと、{"data": "\\u307b\\u3052"}となってしまうため、APIで登録されたデータが、「\ほ\げ」となってしまっている状態です。
can110

2020/07/29 05:29

なるほど。通常のやりとりだとdic1をそのまま渡すだけでよく、文字化けしないはずですが。 クライアント側のコードとサーバ側のアプリの詳細も提示ください。
guest

回答2

0

ベストアンサー

クライアント、サーバの動作が不明ですが、以下のような通常のコードでのやりとりであれば、dic1をそのまま渡すだけで文字化けなく処理できます。

クライアント

Python

1import requests 2 3url = 'http://localhost:8000/' 4headers = {'content-type': 'application/json'} 5 6dic1 = {"data": "\u307b\u3052"} 7dic2 = {"data": "ほげ"} 8for d in [dic1,dic2]: 9 requests.post(url, headers=headers, json=d)

サーバ:参考(curlのGET,POSTのデータを確認

Python

1# curlのGET,POSTのデータを確認 2# https://qiita.com/tkj/items/210a66213667bc038110 3 4import os 5import http.server as s 6from urllib.parse import urlparse 7from urllib.parse import parse_qs 8 9import json 10 11class MyHandler(s.BaseHTTPRequestHandler): 12 def do_POST(self): 13 self.make_data() 14 def do_GET(self): 15 self.make_data() 16 def make_data(self): 17 # urlパラメータを取得 18 parsed = urlparse(self.path) 19 # urlパラメータを解析 20 params = parse_qs(parsed.query) 21 # body部を取得 22 content_len = int(self.headers.get("content-length")) 23 req_body = self.rfile.read(content_len).decode("utf-8") 24 # 返信を組み立て 25 body = "method: " + str(self.command) + "\n" 26 body += "params: " + str(params) + "\n" 27 body += "body : " + req_body + "\n" 28 29 # 確認表示 30 print(body) 31 d = json.loads(req_body) 32 print(d) 33 34 self.send_response(200) 35 self.send_header('Content-type', 'text/html; charset=utf-8') 36 self.send_header('Content-length', len(body.encode())) 37 self.end_headers() 38 self.wfile.write(body.encode()) 39 40host = '0.0.0.0' 41port = 8000 42httpd = s.HTTPServer((host, port), MyHandler) 43print('サーバを起動しました。ポート:%s' % port) 44httpd.serve_forever()

サーバログ

サーバを起動しました。ポート:8000 method: POST params: {} body : {"data": "\u307b\u3052"} {'data': 'ほげ'} 127.0.0.1 - - [29/Jul/2020 14:40:09] "POST / HTTP/1.1" 200 - method: POST params: {} body : {"data": "\u307b\u3052"} {'data': 'ほげ'} 127.0.0.1 - - [29/Jul/2020 14:40:11] "POST / HTTP/1.1" 200 -

投稿2020/07/29 05:47

can110

総合スコア38341

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aoiro27

2020/07/29 05:57

検証したら動作することが確認出来ました! "ユニコードエスケープされた文字列としてPOSTする必要がある" というAPI仕様から、律儀に.encode().decode()してユニコードエスケープ文字列化していましたが、そもそもこれが必要なく、辞書型をjson=でそのまま受け渡すことで暗黙的にサーバサイドにはユニコードエスケープされた状態でPOSTされていることが確認出来ました。 しかも結果、私が原因を認識違いして、質問がずれている形となり申し訳ございません。大変助かりました。ご回答頂いた皆様ありがとうございます。
guest

0

APIのリクエストbodyとしてこのjsonを投げたいのですが、
APIの仕様としてユニコードエスケープされた文字列化する必要があります。
requests.post(url, headers=headers, json=dic1)
と投げる時に、{"data": "\u307b\u3052"}という書式としたいというのがやりたいこととなります。
これが今の状態だと、{"data": "\u307b\u3052"}となってしまうため、APIで登録されたデータが、
「\ほ\げ」となってしまっている状態です。

API 側の JSON の読み取り処理が誤っていないでしょうか?

実験

python

1import json 2 3test = "ほげ".encode("unicode-escape").decode('utf-8') 4print(test == "\u307b\u3052") 5print(test == r"\u307b\u3052") 6print(json.dumps({"data": test}))

実行結果:

console

1$ python test.py 2True 3True 4{"data": "\u307b\u3052"}

ご覧のように、こちらの出力としては間違っていないようです

JSON ではバックスラッシュはバックスラッシュでエスケープする必要があります

参考: Answer: How to escape special characters in building a JSON string?

投稿2020/07/29 05:31

y_shinoda

総合スコア3272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問