I am trying to parse a "complicated" JSON string that is returned to me by an API.
It looks like this:
{
"data":[
["Distance to last strike","23.0","miles"],
["Time of last strike","1/14/2022 9:23:42 AM",""],
["Number of strikes today","1",""]
]
}
While the end goal will be to extract the distance, date/time, as well as count, for right now I am just trying to successfully get the distance.
My python script is:
import requests
import json
response_API = requests.get('http://localhost:8998/api/extra/lightning.json')
data = response_API.text
parse_json = json.loads(data)
value = parse_json['Distance to last strike']
print(value)
This does not work. If I change the value line to
value = parse_json['data']
then the entire string I listed above is returned.
I am hoping it's just a simple formatting issue. Suggestions?
You have an object with a list of lists. If you fetch
value = parse_json['data']
Then you will have a list containing three lists. So:
print(value[0][1])
will print "23.0".
I'm making a program that should save your ip address to a list in a separate file using shelve. Each time it is opened it should put the the ip address in list "pubipcount" in list "pubiplist". When I go to add a new ip I get an error that I don't understand.
I've only ran the code bit by bit to find the part that is broken, and I've taken the liberty of narrowing it down to only the information you need to help me. I've already looked online for a possible answer but I haven't found anything helpful to me.
import shelve
import socket
import urllib.request
save = shelve.open('ip_whitelist', writeback=True)
hostname = socket.gethostname()
PubIP = urllib.request.urlopen('https://ident.me').read().decode('utf8')
LocIP = socket.gethostbyname(hostname)
save['pubipcount'] = 0
save['pubiplist'] = []
save['pubipcount'] = save['pubipcount'] + 1
save['pubiplist']['pubipcount'] = PubIP
This is the exact error:
Traceback (most recent call last):
File "C:\Users\brenn\Desktop\IP\ip.py", line 27, in <module>
save['pubiplist']['pubipcount'] = PubIP
TypeError: list indices must be integers or slices, not str
Shelve allows you use strings as keys but you can't use them as sub-indexes.
The quickest fix would be to interpolate the count into the key:
save[f'pubiplist-{pubipcount}'] = PubIP
if you use a list the index must be integers such as save['pubiplist'][0]
if you want a str as key, you can use a dict instead, change save['pubiplist'] = [] to save['pubiplist'] = {}
for your situation, I suggest you to use PubIP as key, and count PubIP separately:
from collections import defaultdict
# do this only once
save['pubiplist'] = defaultdict(int)
# recieve IP repeately
# update IP and count each time
save['pubiplist'][PubIP] += 1
The problem is ['pubipcount']. In the context it is just a string. I believe you want:
save['pubiplist'][save['pubipcount']] = PubIP
This way you are referring to the value in save['pubipcount'] instead of the string 'pubipcount' as the index.
Edit:
This will likely result in an IndexError, so using append() is better
save['pubiplist'].append(PubIP)
I tried to use the openweathermap.org rest API inside python. When I tried to assign a key from the dictionary I created with the JSON data this error occurred.
-list indices must be integers or slices, not str
I'm new to python and I couldn't find a solution to this matter.
The code snip I wrote:
import requests
from pprint import pprint
lokka = str(input("What is the location you need information of?"))
#takes the location as "lokka"
hellload = requests.get("http://api.openweathermap.org/data/2.5/weather?q="+ lokka +"&appid=xxxxxxxxxxxxxxxxx&units=metric")
#the rest api's load will be taken to the account of hellload
jputha = hellload.json()
#json data will be converted to a dictionary
#print (jputha)
#---------------------------------------------------------
#from now onward I'll be kickin the hell out the jsons
long = str(jputha["coord"]["lon"])
lat = str(jputha["coord"]["lat"])
wthr = str(jputha["weather"]["main"])
temp = str(jputha["main"]["temp"])
winspd = str(jputha["wind"]["speed"])
print(long)
print(lat)
print(wthr)
print(temp)
print(winspd)
According to OpenWeatherMap's documentation, the JSON response from the API looks like this:
{"coord":
{"lon":145.77,"lat":-16.92},
"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],
"base":"cmc stations",
"main":{"temp":293.25,"pressure":1019,"humidity":83,"temp_min":289.82,"temp_max":295.37},
"wind":{"speed":5.1,"deg":150},
"clouds":{"all":75},
"rain":{"3h":3},
"dt":1435658272,
"sys":{"type":1,"id":8166,"message":0.0166,"country":"AU","sunrise":1435610796,"sunset":1435650870},
"id":2172797,
"name":"Cairns",
"cod":200}
where the weather key contains a list of dicts rather than a dict, so if you simply want the first weather data from the list, you should use [0] to obtain the value of the first index instead:
wthr = str(jputha["weather"][0]["main"])
I have an issue with a code I've written. When I run the code I get an error :
Traceback (most recent call last):
File "test23_json_users.py", line 23, in <module>
for user_dict in abc['user_account']['sip_id']:
TypeError: list indices must be integers, not str
The code:
result = '[{"user_account":[{"address":null,"name":null,"country":null,"password":"****","extension":"1112","sip_id":"23001#50.50.50.201","sip_name":"23001","user_id":7973712,"locked":false,"created":null,"h323_name":"1101","city":null,"email":null,"phone":null,"zip":null},{"address":null,"name":null,"country":null,"password":"****","extension":"1113","sip_id":"23002#50.50.50.201","sip_name":"23002","user_id":8847075,"locked":false,"created":null,"h323_name":"1102","city":null,"email":null,"phone":null,"zip":null},{"address":null,"name":null,"country":null,"password":"****","extension":"1114","sip_id":"23003#50.50.50.201","sip_name":"23003","user_id":3680630,"locked":false,"created":null,"h323_name":"1103","city":null,"email":null,"phone":null,"zip":null},{"address":null,"name":null,"country":null,"password":"****","extension":"1115","sip_id":"23004#50.50.50.201","sip_name":"23004","user_id":136391,"locked":false,"created":null,"h323_name":"1104","city":null,"email":null,"phone":null,"zip":null},{"address":null,"name":null,"country":null,"password":"****","extension":"1116","sip_id":"23005#50.50.50.201","sip_name":"23005","user_id":5692227,"locked":false,"created":null,"h323_name":"1105","city":null,"email":null,"phone":null,"zip":null},{"address":null,"name":null,"country":null,"password":"****","extension":"1117","sip_id":"23006#50.50.50.201","sip_name":"23006","user_id":7559026,"locked":false,"created":null,"h323_name":"1106","city":null,"email":null,"phone":null,"zip":null},{"address":null,"name":null,"country":null,"password":"****","extension":"1118","sip_id":"23007#50.50.50.201","sip_name":"23007","user_id":3226075,"locked":false,"created":null,"h323_name":"1107","city":null,"email":null,"phone":null,"zip":null},{"address":null,"name":null,"country":null,"password":"****","extension":"1119","sip_id":"23008#50.50.50.201","sip_name":"23008","user_id":6184875,"locked":false,"created":null,"h323_name":"1108","city":null,"email":null,"phone":null,"zip":null},{"address":null,"name":null,"country":null,"password":"****","extension":"1120","sip_id":"23009#50.50.50.201","sip_name":"23009","user_id":1711112,"locked":false,"created":null,"h323_name":"1109","city":null,"email":null,"phone":null,"zip":null},{"address":null,"name":null,"country":null,"password":"****","extension":"1121","sip_id":"23010#50.50.50.201","sip_name":"23010","user_id":5383101,"locked":false,"created":null,"h323_name":"1110","city":null,"email":null,"phone":null,"zip":null}]}'
params = result[result.find('{"'):]
#print params
abc = json.loads(params)
# Here I'm trying to extract just sip_id from the string result using json.
# I am not able to figure out what went wrong .
for user_dict in abc['user_account']['sip_id']:
print 'usersname : %s' % (user_dict['sip_id'])
Change
for user_dict in abc['user_account']['sip_id']:
to
for user_dict in abc['user_account']:
abc['user_account'] is supposed to be a list.
A list a=['hello',1,2,'people'] has 4 elements accessed by indexes a[0] through a[3].
A dictionary d={'a':1,'b':2} has keys and values. In this case d['a'] has value 1, d[b'] has 2.
If you want to access something in abc['user_account'], type abc['user_account'][42]. If you want to iterate over it
for a in abc['user_account']:
print a
I'm trying to get the hourly forecast from the Wunderground API but my code returns this error.
Traceback (most recent call last):
File "weathergraph.py", line 10, in
forecast = parsed_json['hourly_forecast']['FCTTIME']['temp']['english']
TypeError: list indices must be integers, not str
This is my code.
f=urllib2.urlopen('http://api.wunderground.com/api/mykey/hourly/q/NY/New_York_City.json')
json_string = f.read()
parsed_json = json.loads(json_string)
forecast = parsed_json['hourly_forecast']['FCTTIME']['temp']['english']
f.close()
parsed_json = http://pastie.org/3905346
1) The value of hourly_forecast is a list of dicts, not a dict. Looks like about 36 in the list.
2) temp is not an element of FCTTIME. They are at the same level
This should not generate an error:
forecast = parsed_json['hourly_forecast'][-1]['temp']['english']
It looks like the list is in order by time, so the last one is most recent. Checking the contents of FCTTIME will tell you whether it is different from the last time that you read it.