1. ホーム
  2. python

[解決済み] Python - バイト配列をJSON形式に変換する

2022-10-26 13:47:45

質問

をパースしたい。 bytes の文字列をJSON形式に変換して、pythonのオブジェクトに変換しています。 これが私の持っているソースです。

my_bytes_value = b'[{\'Date\': \'2016-05-21T21:35:40Z\', \'CreationDate\': \'2012-05-05\', \'LogoType\': \'png\', \'Ref\': 164611595, \'Classe\': [\'Email addresses\', \'Passwords\'],\'Link\':\'http://some_link.com\'}]'

そして、これが私の望む望ましい結果なのです。

[{
"Date": "2016-05-21T21:35:40Z",
"CreationDate": "2012-05-05",
"LogoType": "png",
"Ref": 164611595,
"Classes": [
  "Email addresses",
  "Passwords"
],
"Link": "http://some_link.com"}]


まず、バイトを文字列に変換した。

my_new_string_value = my_bytes_value.decode("utf-8")

を呼び出そうとすると loads を使用して、JSONとしてパースします。

my_json = json.loads(my_new_string_value)

このようなエラーが発生します。

json.decoder.JSONDecodeError: Expecting value: line 1 column 174 (char 173)

どのように解決するのですか?

あなたの bytes オブジェクトは <項目 ほとんど JSONですが、ダブルクォートではなくシングルクォートを使っていて、文字列である必要があります。そこで、これを修正する一つの方法として bytesstr に変更し、引用符を置き換えます。もう一つの方法として ast.literal_eval を使うこともできます。詳細は以下を参照してください。もし結果を印刷したり、有効なJSONとしてファイルに保存したい場合は、JSONをPythonのリストにロードして、それを吐き出すことができます。例えば

import json

my_bytes_value = b'[{\'Date\': \'2016-05-21T21:35:40Z\', \'CreationDate\': \'2012-05-05\', \'LogoType\': \'png\', \'Ref\': 164611595, \'Classe\': [\'Email addresses\', \'Passwords\'],\'Link\':\'http://some_link.com\'}]'

# Decode UTF-8 bytes to Unicode, and convert single quotes 
# to double quotes to make it valid JSON
my_json = my_bytes_value.decode('utf8').replace("'", '"')
print(my_json)
print('- ' * 20)

# Load the JSON to a Python list & dump it back out as formatted JSON
data = json.loads(my_json)
s = json.dumps(data, indent=4, sort_keys=True)
print(s)

出力

[{"Date": "2016-05-21T21:35:40Z", "CreationDate": "2012-05-05", "LogoType": "png", "Ref": 164611595, "Classe": ["Email addresses", "Passwords"],"Link":"http://some_link.com"}]
- - - - - - - - - - - - - - - - - - - - 
[
    {
        "Classe": [
            "Email addresses",
            "Passwords"
        ],
        "CreationDate": "2012-05-05",
        "Date": "2016-05-21T21:35:40Z",
        "Link": "http://some_link.com",
        "LogoType": "png",
        "Ref": 164611595
    }
]


Antti Haapalaがコメントで言及しているように、我々は ast.literal_eval を変換するために my_bytes_value をPythonのリストに変換し、一度文字列にデコードします。

from ast import literal_eval
import json

my_bytes_value = b'[{\'Date\': \'2016-05-21T21:35:40Z\', \'CreationDate\': \'2012-05-05\', \'LogoType\': \'png\', \'Ref\': 164611595, \'Classe\': [\'Email addresses\', \'Passwords\'],\'Link\':\'http://some_link.com\'}]'

data = literal_eval(my_bytes_value.decode('utf8'))
print(data)
print('- ' * 20)

s = json.dumps(data, indent=4, sort_keys=True)
print(s)


一般に、この問題は、誰かがデータを保存するために、そのPythonを印刷することによって発生します。 repr を使う代わりに json モジュールを使って、適切な JSON データを作成しています。可能であれば、そもそも適切なJSONデータが作成されるように、その問題を修正したほうがよいでしょう。