验证和格式化JSON文件

35 投票
4 回答
71101 浏览
提问于 2025-04-18 04:36

我有大约2000个JSON文件,想用一个Python程序来处理它们。但是当某个JSON文件格式不正确时,就会出现问题。(错误信息:ValueError: No JSON object could be decoded)这样我就无法把它读入我的程序了。

我现在做的事情大概是这样的:

for files in folder:
    with open(files) as f:
        data = json.load(f); # It causes an error at this part

我知道有一些离线的方法可以验证和格式化JSON文件,但有没有什么编程的方法可以检查和格式化这些文件呢?如果没有,有没有免费的或便宜的替代方案,可以让我在离线时修复这些文件?也就是说,我只需要在包含所有JSON文件的文件夹上运行程序,它就能按要求格式化这些文件?


根据@reece的评论,我解决了这个问题:

invalid_json_files = []
read_json_files = []
def parse():
    for files in os.listdir(os.getcwd()):
        with open(files) as json_file:
            try:
                simplejson.load(json_file)
                read_json_files.append(files)
            except ValueError, e:
                print ("JSON object issue: %s") % e
                invalid_json_files.append(files)
    print invalid_json_files, len(read_json_files)

原来我在工作目录中保存了一个不是JSON格式的文件,而这个目录正好是我读取数据的地方。感谢大家的建议!

4 个回答

0

我不太清楚怎么提供文件夹的路径,所以我想给出一个关于这个选项的回答。

path = r'C:\Users\altz7\Desktop\your_folder_name' # use your path
all_files = glob.glob(path + "/*.json")

data_list = []
invalid_json_files = []

for filename in all_files:
    try:
        df = pd.read_json(filename)
        data_list.append(df)
    except ValueError:
        invalid_json_files.append(filename)

print("Files in correct format: {}".format(len(data_list)))
print("Not readable files: {}".format(len(invalid_json_files)))
#df = pd.concat(data_list, axis=0, ignore_index=True) #will create pandas dataframe 
from readable files, if you like
0

这里有一个完整的 Python3 示例,专门为那些刚接触 Python 的新手准备的。我之前导出了 16000 条记录为 JSON 文件。在这个过程中,我不得不多次重启,所以我需要确认所有的 JSON 文件都是有效的,才能开始导入到新的系统中。

我并不是一个专业的 Python 程序员,所以当我尝试上面提到的代码时,什么也没发生。看起来少了几行代码。下面的示例可以处理当前文件夹或指定文件夹中的文件。

verify.py

import json
import os
import sys
from os.path import isfile,join

# check if a folder name was specified
if len(sys.argv) > 1:
    folder = sys.argv[1]
else:
    folder = os.getcwd()

# array to hold invalid and valid files
invalid_json_files = []
read_json_files = []

def parse():
    # loop through the folder
    for files in os.listdir(folder):
        # check if the combined path and filename is a file
        if isfile(join(folder,files)):
            # open the file
            with open(join(folder,files)) as json_file:
                # try reading the json file using the json interpreter
                try:
                    json.load(json_file)
                    read_json_files.append(files)
                except ValueError as e:
                    # if the file is not valid, print the error 
                    #  and add the file to the list of invalid files
                    print("JSON object issue: %s" % e)
                    invalid_json_files.append(files)
    print(invalid_json_files)
    print(len(read_json_files))
parse()

示例:

python3 verify.py

或者

python3 verify.py somefolder

这个代码是在 Python 3.7.3 上测试过的。

3

是的,有一些方法可以验证一个JSON文件是否有效。一个方法是使用JSON解析库,如果你提供的输入格式不正确,它会抛出异常。

try:
   load_json_file(filename)
except InvalidDataException: # or something
   # oops guess it's not valid

当然,如果你想修复这个问题,你就不能使用JSON加载器,因为这本来就不是有效的JSON。除非你使用的库能够自动为你修复问题,否则你可能就不会有这个疑问了。

一种方法是手动加载文件,把它分解成小块,然后尝试检测错误并在过程中修复它们。不过,我相信有些错误是无法自动修复的,这种情况下最好是抛出一个错误,提醒用户去修正他们的文件。

我自己没有写过JSON修复工具,所以无法提供关于如何实际修复错误的细节。

不过,我不太确定修复所有错误是否是个好主意,因为那样你就得假设你的修复是用户真正想要的。如果是缺少一个逗号或者多了一个多余的逗号,那可能还好,但有些情况下用户想要的可能就不太明确了。

51

内置的 JSON 模块可以用来验证数据格式:

import json

def parse(text):
    try:
        return json.loads(text)
    except ValueError as e:
        print('invalid json: %s' % e)
        return None # or: raise

如果你想处理文件,可以使用:

with open(filename) as f:
    return json.load(f)

这样就可以包含文件名在错误信息里,而不是用 json.loads

在 Python 3.3.5 中,对于 {test: "foo"},我得到的错误是:

invalid json: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

而在 2.7.6 中得到的错误是:

invalid json: Expecting property name: line 1 column 2 (char 1)

这是因为正确的 JSON 格式应该是 {"test": "foo"}

当处理无效的文件时,最好不要继续处理它们。你可以创建一个 skipped.txt 文件,列出出错的文件,这样可以手动检查和修复。

如果可能的话,应该检查生成无效 JSON 文件的网站或程序,修复问题后再重新生成 JSON 文件。否则,你会不断收到新的无效 JSON 文件。

如果没有其他办法,你需要写一个自定义的 JSON 解析器来修复常见错误。这样的话,你应该把原始文件放在版本控制中(或者归档),这样你可以查看和检查自动工具修复的差异(作为 sanity check)。对于模糊的情况,最好还是手动修复。

撰写回答