验证和格式化JSON文件
我有大约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 个回答
我不太清楚怎么提供文件夹的路径,所以我想给出一个关于这个选项的回答。
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
这里有一个完整的 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 上测试过的。
是的,有一些方法可以验证一个JSON文件是否有效。一个方法是使用JSON解析库,如果你提供的输入格式不正确,它会抛出异常。
try:
load_json_file(filename)
except InvalidDataException: # or something
# oops guess it's not valid
当然,如果你想修复这个问题,你就不能使用JSON加载器,因为这本来就不是有效的JSON。除非你使用的库能够自动为你修复问题,否则你可能就不会有这个疑问了。
一种方法是手动加载文件,把它分解成小块,然后尝试检测错误并在过程中修复它们。不过,我相信有些错误是无法自动修复的,这种情况下最好是抛出一个错误,提醒用户去修正他们的文件。
我自己没有写过JSON修复工具,所以无法提供关于如何实际修复错误的细节。
不过,我不太确定修复所有错误是否是个好主意,因为那样你就得假设你的修复是用户真正想要的。如果是缺少一个逗号或者多了一个多余的逗号,那可能还好,但有些情况下用户想要的可能就不太明确了。
内置的 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)。对于模糊的情况,最好还是手动修复。