132

長くて複雑な JSON ファイルからデータをロードする Python コード:

with open(filename, "r") as f:
  data = json.loads(f.read())

(注: 最適なコード バージョンは次のとおりです。

with open(filename, "r") as f:
  data = json.load(f)

ただし、どちらも同様の動作を示します)

多くの種類の JSON エラー (区切り文字の欠落、文字列のバックスラッシュの誤りなど) について、JSON エラーが見つかった行と列の番号を含む便利なメッセージが出力されます。

ただし、他のタイプの JSON エラー (古典的な「リストの最後の項目にカンマを使用する」などのエラーだけでなく、true/false を大文字にするなどの他のエラーも含む) の場合、Python の出力は次のようになります。

Traceback (most recent call last):
  File "myfile.py", line 8, in myfunction
    config = json.loads(f.read())
  File "c:\python27\lib\json\__init__.py", line 326, in loads
    return _default_decoder.decode(s)
  File "c:\python27\lib\json\decoder.py", line 360, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "c:\python27\lib\json\decoder.py", line 378, in raw_decode
    raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded

そのタイプの ValueError の場合、JSON ファイルのどこにエラーがあるかを Python に教えてもらうにはどうすればよいでしょうか?

4

11 に答える 11

180

組み込みモジュールがあいまいsimplejsonである多くの場合、モジュールがより説明的なエラーを出すことがわかりました。jsonたとえば、リストの最後の項目の後にコンマがある場合:

json.loads('[1,2,]')
....
ValueError: No JSON object could be decoded

これはあまり説明的ではありません。と同じ操作simplejson

simplejson.loads('[1,2,]')
...
simplejson.decoder.JSONDecodeError: Expecting object: line 1 column 5 (char 5)

ずっといい!同様に、大文字化などの他の一般的なエラーについても同様ですTrue

于 2013-02-19T11:33:45.710 に答える
15

Python に JSON のどこが間違っているかを教えてもらうことはできません。このような場所でリンターをオンラインで使用する必要があります

これにより、デコードしようとしている JSON のエラーが表示されます。

于 2013-02-15T16:58:05.373 に答える
7

http://code.google.com/p/rson/にある rson ライブラリを試すことができます。PYPI: https://pypi.python.org/pypi/rson/0.9にもアップしているので、 easy_install または pip を使用して取得できます。

トムによって与えられた例:

>>> rson.loads('[1,2,]')
...
rson.base.tokenizer.RSONDecodeError: Unexpected trailing comma: line 1, column 6, text ']'

RSON は JSON のスーパーセットとして設計されているため、JSON ファイルを解析できます。また、人間が見て編集するのにはるかに優れた代替構文もあります。入力ファイルにかなり使用します。

ブール値の大文字化に関しては、rson が誤って大文字化されたブール値を文字列として読み取るようです。

>>> rson.loads('[true,False]')
[True, u'False']
于 2013-02-22T21:07:44.410 に答える
4

私は同様の問題を抱えていましたが、それは一重引用符が原因でした。JSON 標準 ( http://json.org ) では、二重引用符の使用についてのみ言及されているため、Pythonjsonライブラリが二重引用符のみをサポートしている必要があります。

于 2013-08-24T06:20:33.327 に答える
3

私に関しては、私のjsonファイルは非常に大きく、jsonPythonで一般的に使用すると上記のエラーが発生します。

simplejsonによるインストール後sudo pip install simplejson

そして、私はそれを解決しました。

import json
import simplejson


def test_parse_json():
    f_path = '/home/hello/_data.json'
    with open(f_path) as f:
        # j_data = json.load(f)      # ValueError: No JSON object could be decoded
        j_data = simplejson.load(f)  # right
    lst_img = j_data['images']['image']
    print lst_img[0]


if __name__ == '__main__':
    test_parse_json()
于 2018-08-02T08:28:48.883 に答える
0

受け入れられた答えは、問題を解決する最も簡単な答えです。ただし、会社のポリシーにより simplejson のインストールが許可されていない場合は、「リストの最後の項目にカンマを使用する」という特定の問題を修正するために、以下の解決策を提案します。

  1. クラス「JSONDecoder」から継承する子クラス「JSONLintCheck」を作成し、以下のようにクラス「JSONDecoder」のinitメソッドをオーバーライドします。

    def __init__(self, encoding=None, object_hook=None, parse_float=None,parse_int=None, parse_constant=None, strict=True,object_pairs_hook=None)        
            super(JSONLintCheck,self).__init__(encoding=None, object_hook=None,      parse_float=None,parse_int=None, parse_constant=None, strict=True,object_pairs_hook=None)
            self.scan_once = make_scanner(self)
    
  1. make_scannerは、上記のクラスの「scan_once」メソッドをオーバーライドするために使用される新しい関数です。コードはこちら:</li>
  1 #!/usr/bin/env python
  2 from json import JSONDecoder
  3 from json import decoder
  4 import re
  5
  6 NUMBER_RE = re.compile(
  7     r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?',
  8     (re.VERBOSE | re.MULTILINE | re.DOTALL))
  9
 10 def py_make_scanner(context):
 11     parse_object = context.parse_object
 12     parse_array = context.parse_array
 13     parse_string = context.parse_string
 14     match_number = NUMBER_RE.match
 15     encoding = context.encoding
 16     strict = context.strict
 17     parse_float = context.parse_float
 18     parse_int = context.parse_int
 19     parse_constant = context.parse_constant
 20     object_hook = context.object_hook
 21     object_pairs_hook = context.object_pairs_hook
 22
 23     def _scan_once(string, idx):
 24         try:
 25             nextchar = string[idx]
 26         except IndexError:
 27             raise ValueError(decoder.errmsg("Could not get the next character",string,idx))
 28             #raise StopIteration
 29
 30         if nextchar == '"':
 31             return parse_string(string, idx + 1, encoding, strict)
 32         elif nextchar == '{':
 33             return parse_object((string, idx + 1), encoding, strict,
 34                 _scan_once, object_hook, object_pairs_hook)
 35         elif nextchar == '[':
 36             return parse_array((string, idx + 1), _scan_once)
 37         elif nextchar == 'n' and string[idx:idx + 4] == 'null':
 38             return None, idx + 4
 39         elif nextchar == 't' and string[idx:idx + 4] == 'true':
 40             return True, idx + 4
 41         elif nextchar == 'f' and string[idx:idx + 5] == 'false':
 42             return False, idx + 5
 43
 44         m = match_number(string, idx)
 45         if m is not None:
 46             integer, frac, exp = m.groups()
 47             if frac or exp:
 48                 res = parse_float(integer + (frac or '') + (exp or ''))
 49             else:
 50                 res = parse_int(integer)
 51             return res, m.end()
 52         elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
 53             return parse_constant('NaN'), idx + 3
 54         elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
 55             return parse_constant('Infinity'), idx + 8
 56         elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
 57             return parse_constant('-Infinity'), idx + 9
 58         else:
 59             #raise StopIteration   # Here is where needs modification
 60             raise ValueError(decoder.errmsg("Expecting propert name enclosed in double quotes",string,idx))
 61     return _scan_once
 62
 63 make_scanner = py_make_scanner
  1. 「make_scanner」関数を新しい子クラスと一緒に同じファイルに入れることをお勧めします。
于 2018-04-20T08:30:17.567 に答える
-3

「いくつかの長く複雑なJSONファイル」があり、おそらくそれを数回実行する必要があることを考えると、純粋なpython実装よりも最大250倍高速であると主張するcjsonを使用できます(デコーダーは失敗し、最初のエラーを報告します遭遇のみ)。

于 2013-02-26T09:26:26.617 に答える