PythonがこのJSONデータを解析できないのはなぜですか?


1439

ファイルにこのJSONがあります。

{
    "maps": [
        {
            "id": "blabla",
            "iscategorical": "0"
        },
        {
            "id": "blabla",
            "iscategorical": "0"
        }
    ],
    "masks": [
        "id": "valore"
    ],
    "om_points": "value",
    "parameters": [
        "id": "valore"
    ]
}

すべてのJSONデータを出力するためにこのスクリプトを書きました。

import json
from pprint import pprint

with open('data.json') as f:
    data = json.load(f)

pprint(data)

ただし、このプログラムでは例外が発生します。

Traceback (most recent call last):
  File "<pyshell#1>", line 5, in <module>
    data = json.load(f)
  File "/usr/lib/python3.5/json/__init__.py", line 319, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.5/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.5/json/decoder.py", line 355, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 13 column 13 (char 213)

JSONを解析してその値を抽出するにはどうすればよいですか?


@kederrac与えられた理由:「この質問はタイプミスまたはもはや再現できない問題が原因で発生しました。」jsonが無効です。
Rob

@kederracこの問題は、再現できるためではなく、使用方法のエラーが原因で発生します。
Rob

回答:


2128

データが有効なJSON形式ではありません。必要な[]ときに必要なもの{}

  • []listPythonで呼び出されるJSON配列用
  • {}dictPythonで呼び出されるJSONオブジェクト用です

JSONファイルは次のようになります。

{
    "maps": [
        {
            "id": "blabla",
            "iscategorical": "0"
        },
        {
            "id": "blabla",
            "iscategorical": "0"
        }
    ],
    "masks": {
        "id": "valore"
    },
    "om_points": "value",
    "parameters": {
        "id": "valore"
    }
}

次に、コードを使用できます。

import json
from pprint import pprint

with open('data.json') as f:
    data = json.load(f)

pprint(data)

データを使用すると、次のような値も見つけることができます。

data["maps"][0]["id"]
data["masks"]["id"]
data["om_points"]

それらを試してみて、それが理にかなっているかどうかを確認してください。


1
このjsonファイルはJavaオブジェクトから生成されるので、コードを制御する必要があります。ありがとう。
ミシェル

5
解決策をありがとう。印刷中にUnicodeシンボルが表示されます。(例えばu'valore ')。それを防ぐ方法は?
diaryfolio 2015年

6
いいですが、pythonはu'各キーの前にaを追加します。なぜか?
CodyBugstein、2015

7
そのため、テキストのタイプは文字列ではなくユニコードです。ほとんどの場合、ドイツ語のウムラウトや他のモジュール/プログラムなどとテキスト結果を共有するには、Unicodeのテキストを使用することをお勧めします。いいね!
Michael P

2
参考になればと思いますが、皮肉なことに、私は観察をしたいと思います。私は、pprintモジュールが、jsonをきれいに印刷するためのjsonモジュールよりも劣っていることを発見しました。両方試してみれば納得できると思います。私のjsonデータ構造を表示およびデバッグするために、私は次のことを行っています。 dumps()メソッドでの行の折り返しは、好みに合わせて行う必要があります。私の考えが間違っている場合は、誰かに知らせてください。
Larold、2018年

307

次のdata.jsonようになります。

{
 "maps":[
         {"id":"blabla","iscategorical":"0"},
         {"id":"blabla","iscategorical":"0"}
        ],
"masks":
         {"id":"valore"},
"om_points":"value",
"parameters":
         {"id":"valore"}
}

あなたのコードは:

import json
from pprint import pprint

with open('data.json') as data_file:    
    data = json.load(data_file)
pprint(data)

これはwith-statementに依存するため、Python 2.6以降でのみ機能することに注意してください。Python 2.5を使用しfrom __future__ import with_statement、Python <= 2.4を使用している場合は、この回答に基づくJustin Peelの回答を参照してください。

これで、次のような単一の値にアクセスすることもできます。

data["maps"][0]["id"]  # will return 'blabla'
data["masks"]["id"]    # will return 'valore'
data["om_points"]      # will return 'value'

7
私はこれに反対票を得ました。多分それははっきりしていなかった、なぜ私は別の答えが必要だと思ったのか。withステートメントの互換性に関するメモを追加しました。
Bengt 2013

ロールバックして申し訳ありませんが、提案されたコードはdata_file open必要以上に長くなります。
Bengt 2013年

2.6ドキュメント(docs.python.org/2.6/library/io.html)を参照すると、「with」コンテキストでファイルを開くと、ファイルが自動的に閉じます。
スティーブS.

1
@SteveS。はい、ただし、コンテキストが残される前ではありません。pprintでINGのwith-contextは続けdata_fileオープン長いです。
Bengt

1
あなたはのようにアクセス@GayanPathirage data["om_points"]data["masks"]["id"]。「キーパス」を指定することで、辞書のどのレベルにも到達できます。あなたが取得する場合KeyError、例外をそれはキーがパスに存在しないことを意味します。タイプミスに注意するか、辞書の構造を確認してください。
Nuhman、

71

ジャスティンピールの答えは本当に役に立ちますが、Python 3を使用している場合、JSONの読み取りは次のように行う必要があります。

with open('data.json', encoding='utf-8') as data_file:
    data = json.loads(data_file.read())

注:のjson.loads代わりに使用してくださいjson.load。Python 3ではjson.loads、文字列パラメータを取ります。json.loadファイルのようなオブジェクトパラメータを取ります。data_file.read()文字列オブジェクトを返します。

正直なところ、ほとんどの場合、すべてのjsonデータをメモリに読み込むことは問題ではないと思います。


10
なぜPython 3をjson.load支持して避けるべきなの.loadsですか?
Zearin

10
あなたがリンクしたページは、回避について何も言っていませんload
Dan Hulme 2016年

28
この答えは、ファイル全体をメモリに読み込む必要がない場合であり、Python 3ではJSONファイルを遅延読み込みできないことを示唆しています。これは正しくありません。申し訳ありませんが、明らかに反対票です。
ルカシュRogalski

10
この答えは正確ではありません。python3のオープンファイルハンドラーでjson.loadを使用しない理由はありません。反対投票して申し訳ありませんが、上記のコメントを注意深く読んだようではありません。
dusktreader 2016

5
+1この答えは素晴らしいです!それをありがとう、私は文字列を使用できる関数を探すために遠くから私を引っ張りました私はファイルではない文字列とネットワーク要求でしか機能しません!
新規ユーザー

54
data = []
with codecs.open('d:\output.txt','rU','utf-8') as f:
    for line in f:
       data.append(json.loads(line))

8
これは、ファイルに複数のjsonオブジェクトがある場合の正しい解決策です。json.loads複数のjsonオブジェクトをデコードしません。そうしないと、「追加データ」エラーが発生します。
yasin_alm 2016年

これが最良の答えです。それ以外の場合は、「追加データ」エラーが発生します。
Earthx9 2016年

39
ファイルに複数のjsonオブジェクトがあることは、ファイル自体が実際には有効なjsonではないことを意味します。jsonファイルに含めるオブジェクトが複数ある場合は、ファイルの最上位レベルの配列に含める必要があります。
dusktreader 2016

ファイルに複数のjsonオブジェクトがあることは、ファイルが単一のjsonオブジェクトではないことを意味します。それは一種の明白です。オブジェクトから単一の配列を作成することは明らかな回避策です。しかし、JSONは、設計によって明示的(でほぼすべてのレベルで、終了し}]または")。したがって、曖昧さなく、実際に複数のオブジェクトを1つの文字列または1つのファイルに連結できます。ここでの問題は、単一のオブジェクトを期待するパーサーが複数のオブジェクトを渡されたときに失敗することです。
-MSalters

単一のファイルに複数のJSONオブジェクトを格納する広告:そのための「標準」があります- (json lines)にjsonlines.org/examples.jsonlあり、オブジェクトは改行文字で区切られているため、解析の前処理が簡単になり、開始/終了マーカーを気にすることなく、ファイルを簡単に分割/バッチ処理します。
セビ

13

「Ultra JSON」または単に「ujson」は[]、JSONファイルの入力を処理できます。JSON入力ファイルをJSON要素のリストとしてプログラムに読み込んでいる場合。など、[{[{}]}, {}, [], etc...]ujsonは辞書のリスト、リストの辞書の任意の順序を処理できます。

Pythonパッケージインデックスで ujsonを見つけることができ、APIはPythonの組み込みjsonライブラリとほとんど同じです。

大きなJSONファイルをロードする場合も、ujsonははるかに高速です。提供されている同じリンクで、他のPython JSONライブラリと比較してパフォーマンスの詳細を確認できます。


9

Python3を使用している場合は、(connection.jsonファイル)JSONを次のように変更してみてください。

{
  "connection1": {
    "DSN": "con1",
    "UID": "abc",
    "PWD": "1234",
    "connection_string_python":"test1"
  }
  ,
  "connection2": {
    "DSN": "con2",
    "UID": "def",
    "PWD": "1234"
  }
}

次に、次のコードを使用します。

connection_file = open('connection.json', 'r')
conn_string = json.load(connection_file)
conn_string['connection1']['connection_string_python'])
connection_file.close()
>>> test1

1
これは2.7.5でも機能します
siddardha

17
これにより、ファイルハンドルは開いたままになります。withステートメントを使用した方がよい
Corey Goldberg

6

ここでは、変更されたdata.jsonファイルを使用します。

{
    "maps": [
        {
            "id": "blabla",
            "iscategorical": "0"
        },
        {
            "id": "blabla",
            "iscategorical": "0"
        }
    ],
    "masks": [{
        "id": "valore"
    }],
    "om_points": "value",
    "parameters": [{
        "id": "valore"
    }]
}

以下の行を使用して、コンソールでデータを呼び出したり印刷したりできます。

import json
from pprint import pprint
with open('data.json') as data_file:
    data_item = json.load(data_file)
pprint(data_item)

の予想される出力print(data_item['parameters'][0]['id'])

{'maps': [{'id': 'blabla', 'iscategorical': '0'},
          {'id': 'blabla', 'iscategorical': '0'}],
 'masks': [{'id': 'valore'}],
 'om_points': 'value',
 'parameters': [{'id': 'valore'}]}

の予想される出力print(data_item['parameters'][0]['id'])

valore

「マップ」の観測数をカウントする列を追加したい場合、この関数をどのように記述できますか?
Chenxi

5

この解析には2つのタイプがあります。

  1. システムパスからのファイルからのデータの解析
  2. リモートURLからのJSONの解析。

ファイルから、以下を使用できます

import json
json = json.loads(open('/path/to/file.json').read())
value = json['key']
print json['value']

このアークティクルでは、2つのシナリオを使用して値を完全に解析および取得する方法について説明します。Pythonを使用したJSONの解析


4

python3ユーザーとして

loadloadsメソッドの違いは、ファイルからjsonデータを読み取るときに特に重要です。

ドキュメントで述べたように:

json.load:

この変換テーブルを使用して、fp(.read()対応のテキストファイルまたはJSONドキュメントを含むバイナリファイル)をPythonオブジェクトにデシリアライズします。

json.loads:

json.loads:この変換テーブルを使用して、s(JSONドキュメントを含むstr、bytesまたはbytearrayインスタンス)をPythonオブジェクトにデシリアライズします。

json.loadメソッドは、バイナリファイルを読み取ることができるため、開いているjsonドキュメントを直接読み取ることができます。

with open('./recipes.json') as data:
  all_recipes = json.load(data)

その結果、この変換テーブルに従って指定された形式でjsonデータを使用できます。

https://docs.python.org/3.7/library/json.html#json-to-py-table


これは、質問に対する答えです。ユーザーは正しい方法を使用してjsonファイルをロードしていました。
Raj006
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.