I have this code.
import json
with open('data5.json', 'r') as myfile:
data = myfile.read()
data_2 = data.replace('[', ' ')
data_3 = data_2.replace(']', ' ')
print(data_3)
My variable data_3 is like that:
{"Manufacturer": "VMware, Inc.", "Model": "VMware7,1", "Name": "DC01"} , {"Index": "1", "IPAddress": "192.168.1.240,fe80::350e:d28d:14a5:5cbb" }
I want to parse this. I want to get the value of Manufacturer or Model or Name. After parsing i will save them into the database. How can i do it?
import json
with open('data5.json', 'r') as myfile:
data = json.load(myfile)
for i in data:
print(data['Name'])
I tried this code for getting Name.
It gives me error
Traceback (most recent call last):
File "C:\Users\DELL\AppData\Roaming\JetBrains\PyCharmCE2021.3\scratches\scratch_38.py", line 5, in <module>
print(data['Name'])
TypeError: list indices must be integers or slices, not str
Your data is json, so use the json library from the stdlib:
import json
with open('data5.json', 'r') as myfile:
data = json.load(myfile)
No need to do any manual parsing.
Related
I am in the process of doing a conversion of JSON to XML using Python.
I'm giving a presentation of how by starting with one file, CSV, you can convert it through multiple formats in a chain. So, CSV to JSON, that JSON to XML, XML to the next file type in the chain, etc, back to CSV.
I obtained a public domain CSV file from Kaggle (https://www.kaggle.com/canggih/anime-data-score-staff-synopsis-and-genre), then converted it to JSON.
From JSON, I am trying to convert to XML and write to an outfile.
I converted the CSV to JSON using this (no formatting, just a straight conversion):
#This should convert CSV to JSON
import json, os
import pandas as pd
import csv
df = pd.read_csv('dataanime.csv')
df.to_json(r'sassyg_data_Anime.json')
Then, I created my JSON to XML file:
#With help from instructor and CodeSpeedy
#https://www.codespeedy.com/how-to-convert-json-to-xml-using-python/
#Import libraries
import json as j
import xml.etree.ElementTree as et
#load in the json file
with open("sassyg_data_Anime.json") as json_file_format:
d = j.load(json_file_format)
#create the main container element for the entire XML file
r = et.Element("Work")
#creates the subelements for each part of the json file
et.SubElement(r,"Title").text = d["Title"]
et.SubElement(r,"Type").text = d["Type"]
et.SubElement(r,"Episodes").text = d["Episodes"]
et.SubElement(r,"Status").text = d["Status"]
et.SubElement(r,"Start airing").text = str(d["Start airing"])
et.SubElement(r,"End airing").text = str(d["End airing"])
et.SubElement(r,"Starting season").text = d["Starting season"]
et.SubElement(r,"Broadcast time").text = d["Broadcast time"]
et.SubElement(r,"Producers").text = d["Producers"]
et.SubElement(r,"Licensors").text = d["Licensors"]
et.SubElement(r,"Studios").text = d["Studios"]
et.SubElement(r,"Sources").text = d["Sources"]
et.SubElement(r,"Genres").text = d["Genres"]
et.SubElement(r,"Duration").text = str(d["Duration"])
et.SubElement(r,"Rating").text = d["Rating"]
et.SubElement(r,"Score").text = str(d["Score"])
et.SubElement(r,"Scored by").text = str(d["Scored by"])
et.SubElement(r,"Members").text = str(d["Members"])
et.SubElement(r,"Favorites").text = str(d["Favorites"])
et.SubElement(r,"Description").text = d["Description"]
#create the element tree/info for the write file
a = et.ElementTree(r)
#ERROR ERROR
#structure the output for xml via tostring rather than str
#Cannot write an ElementTree to file, errors out
#This was one solution I came up with, still errors out
a_xml_str = et.tostring(a)
print(a_xml_str)
#This might error out as well, I can't get the program to get to this point
#write file it should go to
outfile = open("json_to_xml.xml", 'w', encoding='utf-8')
outfile.write(a_xml_str)
outfile.close()
The error I get is:
Traceback (most recent call last):
File "F:\Data_Int_Final\Gardner_json_to_xml\convert_json_to_xml.py", line 44, in <module>
a_xml_str = et.tostring(a)
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\xml\etree\ElementTree.py", line 1109, in tostring
ElementTree(element).write(stream, encoding,
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\xml\etree\ElementTree.py", line 748, in write
serialize(write, self._root, qnames, namespaces,
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\xml\etree\ElementTree.py", line 873, in _serialize_xml
tag = elem.tag
AttributeError: 'ElementTree' object has no attribute 'tag'
This is the latest version of the code I've tried. Can anyone see a solution?
Update:
I have two other ways to convert to the starting JSON file, would one of these be a better approach?
import json
import csv
def make_json(csvFilePath, jsonFilePath):
data = {}
with open(csvFilePath, encoding='utf-8') as csvf:
csvReader = csv.DictReader(csvf)
for rows in csvReader:
key = rows['Title']
data[key] = rows
with open(jsonFilePath, 'w', encoding='utf-8') as jsonf:
jsonf.write(json.dumps(data, indent=4))
csvFilePath = r'dataanime.csv'
jsonFilePath = r'dataAnime.json'
make_json(csvFilePath, jsonFilePath)
which errors out my XML conversion when I use this JSON file with it:
Traceback (most recent call last):
File "F:\Data_Int_Final\convert_json_to_xml.py", line 16, in <module>
et.SubElement(r,"Title").text = d["Title"]
KeyError: 'Title'
or:
import csv
import json
import time
def csv_to_json(csvFilePath, jsonFilePath):
jsonArray = []
#read csv file
with open(csvFilePath, encoding='utf-8') as csvf:
#load csv file data using csv library's dictionary reader
csvReader = csv.DictReader(csvf)
#convert each csv row into python dict
for row in csvReader:
#add this python dict to json array
jsonArray.append(row)
#convert python jsonArray to JSON String and write to file
with open(jsonFilePath, 'w', encoding='utf-8') as jsonf:
jsonString = json.dumps(jsonArray, indent=4)
jsonf.write(jsonString)
csvFilePath = r'dataanime.csv'
jsonFilePath = r'g_d_anime.json'
start = time.perf_counter()
csv_to_json(csvFilePath, jsonFilePath)
finish = time.perf_counter()
print(f"Conversion of all rows completed successfully in {finish - start:0.4f} seconds")
which errors out my XML conversion when I use this created JSON file with it:
Traceback (most recent call last):
File "F:\Data_Int_Final\convert_json_to_xml.py", line 16, in <module>
et.SubElement(r,"Title").text = d["Title"]
TypeError: list indices must be integers or slices, not str
It's simpler to work with the CSV file and generate a XML file from that directly.
Try something like this:
import csv
import xml.etree.ElementTree as et
root = et.Element('WorksXML')
tree = et.ElementTree(root)
with open("dataanime.csv", "r", encoding="utf-8") as fin:
reader = csv.DictReader(fin)
for row in reader:
r = et.SubElement(root, "Work")
# iterate over each of the fields and add to the XML element
for field in reader.fieldnames:
et.SubElement(r, field.replace(' ', '_')).text = row[field]
with open("csv_to_xml.xml", 'wb') as fout:
tree.write(fout, xml_declaration=True, encoding='utf-8')
This generates an XML file with each "work" as a separate sub-element under the root element.
<?xml version="1.0" encoding="utf-8"?>
<WorksXML>
<Work>
<Title>Fullmetal Alchemist: Brotherhood</Title>
<Type>TV</Type>
<Episodes>64</Episodes>
<Status>Finished Airing</Status>
<Start_airing>4/5/2009</Start_airing>
<End_airing>7/4/2010</End_airing>
<Starting_season>Spring</Starting_season>
...
For the CSV to JSON conversion, the first approach creates a dictionary with titles as keys and the second approach creates an array with each item an object with all the attributes.
If any of the works have a duplicate title then the first approach will overwrite the duplicate entries. If not then it's just a matter of how you want to access the data in the JSON file as a dictionary or a list. If you want to generate XML from the JSON file then the second approach with an array will be the better option.
To convert the array-based JSON file to XML then this will do the job.
import json
import xml.etree.ElementTree as ET
def json_to_xml(jsonFilePath, xmlFilePath):
root = ET.Element('WorksXML')
tree = ET.ElementTree(root)
with open(jsonFilePath, "r", encoding="utf-8") as fin:
jdata = json.load(fin)
for obj in jdata:
r = ET.SubElement(root, "Work")
for key, value in obj.items():
ET.SubElement(r, key.replace(' ', '_')).text = value
with open(xmlFilePath, 'wb') as fout:
tree.write(fout, xml_declaration=True, encoding='utf-8')
jsonFilePath = 'g_d_anime.json'
xmlFilePath = 'g_d_anime.xml'
json_to_xml(jsonFilePath, xmlFilePath)
So I have been attempting to create a file to convert json files to csv files using a template i found online. However, I keep receiving the following error:
header = User.keys()
AttributeError: 'str' object has no attribute 'keys'
Here is the code I'm using:
# Python program to convert
# JSON file to CSV
import json
import csv
# Opening JSON file and loading the data
# into the variable data
with open('/Users/jhillier5/Downloads/mentalhealthcheck-in-default-rtdb-export (1).json') as json_file:
data = json.load(json_file)
User_data = data['User']
# now we will open a file for writing
data_file = open('data_file.csv', 'w')
# create the csv writer object
csv_writer = csv.writer(data_file)
# Counter variable used for writing
# headers to the CSV file
count = 0
print(User_data)
print(type(User_data))
for User in User_data:
if count == 0:
# Writing headers of CSV file
header = User.keys()
csv_writer.writerow(header)
count += 1
# Writing data of CSV file
csv_writer.writerow(User.values())
data_file.close()
I simply don't understand why there is a string object and not a dict. I double checked and User_data is stored as a dict but i still get the error.
The json is organised in the following format:
{
"User" : {
"-MlIoVUgATqwtD_3AeCb" : {
"Aid" : "1",
"Gender" : "1",
"Grade" : "11",
}
}
}
In this for loop
for User in User_data:
if count == 0:
# Writing headers of CSV file
header = User.keys()
csv_writer.writerow(header)
count += 1
# Writing data of CSV file
csv_writer.writerow(User.values())
You are iterating through User_data, so User will be ["MlIoVUgATqwtD_3AeCb", ...]. In order to get the keys of that user data you should index it this way -
header = User_data[User].keys()
I am using a windows machine running python 3.7.4.
Currently I am trying to use the flashText library to process a .txt file to count the number of occurrences of characters that I selected and running into errors while processing the file.
My code is as follows
from flashtext import KeywordProcessor
#making a dictionary of major charaters
#a few major players for now
keyword_processor = KeywordProcessor(case_sensitive=False)
keyword_dict = {
"Eddard" : ["ned", "eddard"],
"Daenerys" : ["dany", "khaleesi"],
"john" : ["john snow", "bastard"],
"Tyrion" : ['imp', 'halfman' , 'tyrion Lannister' ],
"bran" : ['bran stark']
}
keyword_processor.add_keywords_from_dict(keyword_dict)
text_file = open("gameofthrones.txt", "r" , encoding="utf8")
keywords_found = keyword_processor.extract_keywords(text_file)
print(keywords_found)
text_file.close()
I am getting an error that I don't quite understand:
C:\Users\MLMir\Desktop\python>stackoverflow.py
Traceback (most recent call last):
File "C:\Users\MLMir\Desktop\python\stackoverflow.py", line 24, in <module>
keywords_found = keyword_processor.extract_keywords(text_file)
File "C:\Users\MLMir\Anaconda3\lib\site-packages\flashtext\keyword.py", line 475, in extract_keywords
sentence = sentence.lower()
AttributeError: '_io.TextIOWrapper' object has no attribute 'lower'
I've tried changing this to a list but that just threw a different attribute error.
Need to read the text file in python after opening it.
Try below:
from flashtext import KeywordProcessor
#making a dictionary of major charaters
#a few major players for now
keyword_processor = KeywordProcessor(case_sensitive=False)
keyword_dict = {
"Eddard" : ["ned", "eddard"],
"Daenerys" : ["dany", "khaleesi"],
"john" : ["john snow", "bastard"],
"Tyrion" : ['imp', 'halfman' , 'tyrion Lannister' ],
"bran" : ['bran stark']
}
keyword_processor.add_keywords_from_dict(keyword_dict)
text_file = open("gameofthrones.txt",'r', encoding="utf8")
raw = text_file.read()
keywords_found = keyword_processor.extract_keywords(raw)
print(keywords_found)
text_file.close()
At first, it makes no sense to search an empty file for keywords.
Second, the method extract_keywords expects a string, not a file. lower is not a method of file.
I want to make json from text file, and make list value of ['ids']
{"previous_cursor": 0, "previous_cursor_str": "0", "next_cursor": 1351473067174597097, "ids": [250718906, 66612533], "next_cursor_str": "1351473067174597097"} {"previous_cursor": -1351352880715992572, "previous_cursor_str": "-1351352880715992572", "next_cursor": 0, "ids": [113030689, 22020972], "next_cursor_str": "0"}
My code
import json
f = open('22580877','r')
data = f.read()
datalist = data.split('\n')
idslist = []
for i in datalist:
datadic = eval(i)
print(datadic['ids'])
idslist.extend(datadic['ids'])
datadic = {}
for j in idslist:
print(j)
f.close()
the error msg is
Traceback (most recent call last):
File "test.py", line 11, in <module>
datadic = eval(i)
File "<string>", line 0
^
SyntaxError: unexpected EOF while parsing
I can't find my syntaxerror in my code. help me please!
It sounds like you've been handed a file with a jsonified string on each line of the file. From your error message I kinda wonder if your file is corrupt or not formatted the way you think it is. However, if I had been given the task you've supplied I'd do something like this...
import json, traceback
idslist = []
with open('22580877', 'r') as f:
data = f.read()
datalist = data.split('\n')
for idx, json_string in enumerate(datalist):
try:
json_obj = json.loads(json_string)
idslist.extend(json_obj['ids'])
except:
print "bad json on line {} with traceback:\n{}".format(idx+1, traceback.format_exc())
for id in idslist:
print(id)
I understand the very basics of programming in python and here is my problem. I have following json file from the developer API for League of Legends (a video game) (excerpt):
"keys": {
"35": "Shaco",
"36": "DrMundo",
"33": "Rammus",
AND SO ON..
},
"data": {
"Aatrox": {
"tags": [
"Fighter",
"Tank"
],
"stats": {
"attackrange": 150,
"mpperlevel": 45,
"mp": 105.6,
"attackdamage": 60.376,
AND SO ON...
},
AND SO ON.
My code:
#import dependencies
#to understand json
import json
#to write csv file
import csv
#to output json in a readable way in the command line
from pprint import pprint
#create the output file
outfile_path='output.csv'
#open up the file and tell the programm to write in it
writer = csv.writer(open(outfile_path, 'w'))
#Create custom headers for the data
headers =['armor', 'armorperlevel', 'attackdamage','attackdamageperlevel','attackrange', 'attackspeedoffset', 'attackspeedperlevel', 'crit', 'critperlevel', 'hp', 'hpperlevel', 'hpregen', 'hpregenperlevel', 'movespeed', 'mp', 'mpperlevel', 'mpregen', 'mpregenperlevel', 'spellblock', 'spellblockperlevel']
writer.writerow(headers)
#open data file, in order to manipulate it
with open('data.json') as data_file:
data = json.load(data_file)
#print stats for the keys Aatrox
aatrox = data['data']['Aatrox']['stats']
pprint(aatrox)
What I have done so far:
I was able to load the file in my program
I created custom headers in a csv file
I am able to print the data for a specific "keys" (ex: Aatrox)
I can also print the "stats" of a specific "keys"
What I would like to do now:
Create a line in a CSV-file for each "keys" with the "stats"-value separated by commas
I believe that I will be able to create a loop that goes through all the keys by myself. However I fail to find easy to understand information on how to write the dictionary to a CSV-file in my desired format.
Could anyone help me out with this. What I am most interested in understanding is:
How do I write a dictionary-value to a string with a specific format?
How can I tell python to put the dictionary-value under the correct
header, which I have specified?
You could use a csv.DictWriter:
import csv
stats = {
"attackrange": 150,
"mpperlevel": 45,
"mp": 105.6,
"attackdamage": 60.376,}
headers =['attackdamage','attackrange', 'mp', 'mpperlevel']
with open('output.csv', 'wb') as f:
writer = csv.DictWriter(
f, headers, delimiter=',', lineterminator='\n', )
writer.writeheader()
writer.writerow(stats)
produces output.csv:
attackdamage,attackrange,mp,mpperlevel
60.376,150,105.6,45