我正在尝试将JSON文件转换为CSV文件并接收AttributeError:'str'对象没有带有以下代码的属性'get'错误。有人请告诉我如何解决它?谢谢。
from sys import argv
from os import path
from types import *
import argparse
import logging
import json
import csv
def main():
parser = argparse.ArgumentParser(
description='Convert json file to csv'
)
parser.add_argument(
'-i',
'--input_file',
dest='input_file',
default=None,
required=True,
help='Source json file (mandatory)'
)
parser.add_argument(
'-o',
'--output_file',
dest='output_file',
default=None,
required=True,
help='Destination csv file (mandatory)'
)
args = parser.parse_args()
input_file = args.input_file
output_file = args.output_file
json_data = []
data = None
write_header = True
item_keys = []
with open(input_file) as json_file:
json_data = json_file.read()
try:
data = json.loads(json_data)
except Exception as e:
raise e
with open(output_file, 'wb') as csv_file:
writer = csv.writer(csv_file)
for item in data:
item_values = []
for key in item:
if write_header:
item_keys.append(key)
value = item.get(key, '')
if isinstance(value, StringTypes):
item_values.append(value.encode('utf-8'))
else:
item_values.append(value)
if write_header:
writer.writerow(item_keys)
write_header = False
writer.writerow(item_values)
if __name__ == "__main__":
main()
以下是sample file
以下是格式化版本:
{
"off_ball_screens": [
{
"possession_id": "20131029121_0",
"outcomes": [],
"cutter_defender": 862504243765291,
"oteam": 12,
"game_code": 2013102912,
"led_to_shot": false,
"location_x": 17.57135,
"location_y": 36.37835,
"led_to_touch": false,
"screener_def_type": "jam",
"cutter_def_type": "whip",
"screener": 698955898567260,
"cutter": 716891544080147,
"season": 2013,
"dteam": 22,
"type": "Wide Pin",
"frame": 303,
"chance_id": "20131029121_0_0",
"id": "2013102912_1_303_698955898567260_716891544080147",
"period": 1,
"direct": false,
"game_clock": 713.9400024414062,
"screener_defender": 1038700886052194
},
{
"possession_id": "20131029121_0",
"outcomes": [],
"cutter_defender": 862504243765291,
"oteam": 12,
"game_code": 2013102912,
"led_to_shot": false,
"location_x": 7.12878,
"location_y": 21.16205,
"led_to_touch": false,
"screener_def_type": "drop",
"cutter_def_type": "trail",
"screener": 842413156760236,
"cutter": 716891544080147,
"season": 2013,
"dteam": 22,
"type": "Down",
"frame": 405,
"chance_id": "20131029121_0_0",
"id": "2013102912_1_405_842413156760236_716891544080147",
"period": 1,
"direct": false,
"game_clock": 709.5399780273438,
"screener_defender": 960969254745795
},
{
"possession_id": "20131029121_0",
"outcomes": [
"PASS",
"AST2"
],
"cutter_defender": 715506781586579,
"oteam": 12,
"game_code": 2013102912,
"led_to_shot": false,
"location_x": 12.18125,
"location_y": 17.70263,
"led_to_touch": true,
"screener_def_type": "jam",
"cutter_def_type": "trail",
"screener": 374399613395349,
"cutter": 42597133322477,
"season": 2013,
"dteam": 22,
"type": "Zipper",
"frame": 727,
"chance_id": "20131029121_0_1",
"id": "2013102912_1_727_374399613395349_42597133322477",
"period": 1,
"direct": true,
"game_clock": 699.0,
"screener_defender": 217592361774498
}
]
}
答案 0 :(得分:0)
您的data
变量包含整个JSON,它只有一个密钥:"off_ball_screens"
。因此,当您使用item
迭代它时,它实际上只是单个键本身。您可以使用"off_ball_screens"
访问data[item]
正在编制索引的列表,但是当您尝试迭代item
时,您实际上正在迭代字符串值,而不是一个get()
函数。
你可以试试这个:
def main():
parser = argparse.ArgumentParser(description='Convert json file to csv')
parser.add_argument(
'-i',
'--input_file',
dest='input_file',
default=None,
required=True,
help='Source json file (mandatory)'
)
parser.add_argument(
'-o',
'--output_file',
dest='output_file',
default=None,
required=True,
help='Destination csv file (mandatory)'
)
args = parser.parse_args()
input_file = args.input_file
output_file = args.output_file
json_data = []
data = None
write_header = True
item_keys = []
with open(input_file) as json_file:
json_data = json_file.read()
try:
data = json.loads(json_data)
except Exception as e:
raise e
with open(output_file, 'w') as csv_file:
writer = csv.writer(csv_file)
data = data["off_ball_screens"]
for item in data:
item_values = []
for key in item:
if write_header:
item_keys.append(key)
value = item.get(key, '')
if isinstance(value, StringTypes):
item_values.append(value.encode('utf-8'))
else:
item_values.append(value)
if write_header:
writer.writerow(item_keys)
write_header = False
writer.writerow(item_values)