I am using an API that returns a JSON object that has "encoded_polyline"
fields that tend to result in errors like this one:
UnicodeEncodeError: 'utf-8' codec can't encode character '\udb6e' in position 2: surrogates not allowed
Since the offending fields don't offer useful data, I decided the best would be to get rid of the fields causing these errors. However, these fields are sometimes stored at the top level of the JSON object but also sometimes stored within an array at either:
jsonobject["points"]["points"]
jsonobject["laps"]["metric"]
jsonobject["laps"]["imperial"]
I think I've finally got something working to hunt down all these fields and delete them, but I have a feeling this could be done much more cleanly.
r = requests.get(url, headers = {'User-Agent':UA})
jsonobject = r.json()
if 'laps' in jsonobject and jsonobject['laps'] is not None:
if 'imperial' in jsonobject['laps']:
laps_array = jsonobject['laps']['imperial']
type = 'imperial'
if 'metric' in jsonobject['laps']:
laps_array = jsonobject['laps']['metric']
type = 'metric'
if laps_array is not None:
jsonobject['laps_correct'] = dict()
jsonobject['laps_correct'][type] = list()
for document in laps_array:
#sometimes these document objects turn out to be dicts
#and sometimes they turn out to be strings
#even though JSON output is always the same
#is there a better way to deal with this?
if document.__class__.__name__ == "dict":
document2 = document
else:
document2 = json.loads(document)
if 'small_encoded_polyline' in document2 and document2['small_encoded_polyline'] is not None:
del document2['small_encoded_polyline']
document = document2
#I thought this line above would modify the original
#jsonobject since document is a dictionary so I should
#be working with a pointer to the original object
#but inspection of jsonobject reveals this not to be the case
jsonobject['laps_correct'][type].append(document2)
del jsonobject['laps']
jsonobject['laps'] = jsonobject.pop('laps_correct')
# this can't be an elif because sometimes json objects
# have both "points" and "laps"
if 'points' in jsonobject and jsonobject['points'] is not None:
if 'points' in jsonobject['points']:
laps_array = jsonobject['points']['points']
jsonobject['points_correct'] = dict()
jsonobject['points_correct']['points'] = list()
if laps_array is not None:
for document in laps_array:
if document.__class__.__name__ == "dict":
document2 = document
else:
document2 = json.loads(document)
if 'small_encoded_polyline' in document2 and document2['small_encoded_polyline'] is not None:
del document2['small_encoded_polyline']
document = document2
jsonobject['points_correct']['points'].append(document2)
del jsonobject['points']
jsonobject['points'] = jsonobject.pop('points_correct')
if 'small_encoded_polyline' in jsonobject and jsonobject['small_encoded_polyline'] is not None:
del jsonobject['small_encoded_polyline']
My two biggest worries/questions are:
- How can I deal with variables that are sometimes typed as dicts and sometimes as strings even though the JSON format appears identical in both cases?
- Is it really necessary to delete original key and replace it rather than updating dicts from the original key? This seems slow and clunky.
r
come from? I suspect that that is the root cause of the problem. \$\endgroup\$r.headers['content-type']
say? \$\endgroup\$