I have stitched together the below python code and I'm struggling with a KeyError: 'vrm'
.
My aim is to parse the JSON string and only print the specific JSON objects.
#!/usr/bin/python3
import json
class Vehicle:
def __init__(self,responseInfo, code, desc, data, vrm, vin, engineNumber, capId, capCode, manufacturer, model, vehicleType, registrationDate, firstRegistrationDate, body, doors, engineSize, fuel, fuelDelivery, transmission, isScraped, isExported, isImported, images, exactMatch, url, mainImage):
self.responseInfo = responseInfo
self.code = code
self.desc = desc
self.data = data
self.vrm = vrm
self.vin = vin
self.engineNumber = engineNumber
self.capId = capId
self.capCode = capCode
self.manufacturer = manufacturer
self.model = model
self.vehicleType = vehicleType
self.registrationDate = registrationDate
self.firstRegistrationDate = firstRegistrationDate
self.body = body
self.doors = doors
self.engineSize = engineSize
self.fuel = fuel
self.fuelDelivery = fuelDelivery
self.transmission = transmission
self.isScraped = isScraped
self.isExported = isExported
self.isImported = isImported
self.images = images
self.exactMatch = exactMatch
self.url = url
self.mainImage = mainImage
def vehicleDecoder(obj):
return Vehicle(obj['vrm'], obj['vin'], obj['engineNumber'], obj['capId'], obj['capCode'], obj['manufacturer'], obj['model'], obj['vehicleType'], obj['registrationDate'], obj['firstRegistrationDate'], obj['body'], obj['doors'], obj['engineSize'], obj['fuel'], obj['fuelDelivery'], obj['transmission'], obj['isScraped'], obj['isExported'], obj['isImported'], obj['images'], obj['exactMatch'], obj['url'], obj['mainImage'])
vehicleObj = json.loads('{"responseInfo":{"code":0,"desc":"Success"},"data":{"vrm":"MA71VWG","vin":"WBATS120009H40802","engineNumber":"A1566412","capId":91400,"capCode":"BMX320MS 5EXTA4 4","manufacturer":"BMW","model":"X3","vehicleType":"Car","registrationDate":"27/09/21","firstRegistrationDate":"27/09/21","body":"Estate","doors":"5","engineSize":"1998","fuel":"Petrol/PlugIn Elec Hybrid","fuelDelivery":"Turbo","transmission":"Automatic","isScraped":"No","isExported":"No","isImported":"No","images":[{"viewpoint":"Front Three Quarter","exactMatch":true,"url":"https://soap.cap.co.uk/images/VehicleImage.aspx?SUBID=171774&HASHCODE=92A987528AB2F2215A7372DADD8CE57C&DB=CAR&CAPID=91400&WIDTH=&HEIGHT=&IMAGETEXT=&VIEWPOINT=3","mainImage":true}]}}')
print(vehicleObj) #works
#vehicleObj = (vehicleObj['data'])
print(vehicleObj) #works
vehicleObj = json.dumps(vehicleObj)
print(vehicleObj)
vehicleObj = json.loads(str(vehicleObj), object_hook=vehicleDecoder)
#print(vehicleObj)
print(vehicleObj.vrm, vehicleObj.vin, vehicleObj.engineNumber, vehicleObj.capId, vehicleObj.capCode, vehicleObj.manufacturer, vehicleObj.model, vehicleObj.vehicleType, vehicleObj.registrationDate, vehicleObj.firstRegistrationDate, vehicleObj.body, vehicleObj.doors, vehicleObj.engineSize, vehicleObj.fuel, vehicleObj.fuelDelivery, vehicleObj.transmission, vehicleObj.isScraped, vehicleObj.isExported, vehicleObj.isImported)
Error output below
Traceback (most recent call last):
File "C:\Users\jack\Desktop\Python-Project\test.py", line 42, in <module>
vehicleObj = json.loads(str(vehicleObj), object_hook=vehicleDecoder)
File "C:\Python\Python39\lib\json\__init__.py", line 359, in loads
return cls(**kw).decode(s)
File "C:\Python\Python39\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Python\Python39\lib\json\decoder.py", line 353, in raw_decode
obj, end = self.scan_once(s, idx)
File "C:\Users\jack\Desktop\Python-Project\test.py", line 34, in vehicleDecoder
return Vehicle(obj['vrm'], obj['vin'], obj['engineNumber'], obj['capId'], obj['capCode'], obj['manufacturer'], obj['model'], obj['vehicleType'], obj['registrationDate'], obj['firstRegistrationDate'], obj['body'], obj['doors'], obj['engineSize'], obj['fuel'], obj['fuelDelivery'], obj['transmission'], obj['isScraped'], obj['isExported'], obj['isImported'], obj['images'], obj['exactMatch'], obj['url'], obj['mainImage'])
KeyError: 'vrm'
Can anyone spot where I've gone wrong or have a better solution to parse JSON output?
CodePudding user response:
If you reduce this example down to the minimum required to trigger the problem, the issue is much more clear:
import json
class Vehicle:
def __init__(self, vrm):
self.vrm = vrm
def vehicleDecoder(obj):
return Vehicle(obj['vrm'])
vehicle_str = '{"data":{"vrm":"MA71VWG"}}'
vehicleObj = json.loads(vehicle_str, object_hook=vehicleDecoder)
This still creates a KeyError. Why? When loading a json, the object hook is called on every object. You probably intended for it to be called on the object containing the "vrm" key, but technically the {"data": ...
part is an object too.
How can you fix this? Don't use object_hook. Parse the json like this:
vehicleJson = json.loads(...)
vehicleObj = vehicleDecoder(vehicleJson['data'])
CodePudding user response:
This does what you ask, in a simpler way.
#!/usr/bin/python3
import json
from pprint import pprint
class Vehicle:
def __init__(self, obj):
self.__dict__.update( obj['data'] )
self.__dict__.update( self.images[0] )
vehicleObj = json.loads('{"responseInfo":{"code":0,"desc":"Success"},"data":{"vrm":"MA71VWG","vin":"WBATS120009H40802","engineNumber":"A1566412","capId":91400,"capCode":"BMX320MS 5EXTA4 4","manufacturer":"BMW","model":"X3","vehicleType":"Car","registrationDate":"27/09/21","firstRegistrationDate":"27/09/21","body":"Estate","doors":"5","engineSize":"1998","fuel":"Petrol/PlugIn Elec Hybrid","fuelDelivery":"Turbo","transmission":"Automatic","isScraped":"No","isExported":"No","isImported":"No","images":[{"viewpoint":"Front Three Quarter","exactMatch":true,"url":"https://soap.cap.co.uk/images/VehicleImage.aspx?SUBID=171774&HASHCODE=92A987528AB2F2215A7372DADD8CE57C&DB=CAR&CAPID=91400&WIDTH=&HEIGHT=&IMAGETEXT=&VIEWPOINT=3","mainImage":true}]}}')
pprint(vehicleObj)
vehicleObj = Vehicle(vehicleObj)
print(vehicleObj.vrm, vehicleObj.vin, vehicleObj.engineNumber, vehicleObj.capId, vehicleObj.capCode, vehicleObj.manufacturer, vehicleObj.model, vehicleObj.vehicleType, vehicleObj.registrationDate, vehicleObj.firstRegistrationDate, vehicleObj.body, vehicleObj.doors, vehicleObj.engineSize, vehicleObj.fuel, vehicleObj.fuelDelivery, vehicleObj.transmission, vehicleObj.isScraped, vehicleObj.isExported, vehicleObj.isImported)
Output:
MA71VWG WBATS120009H40802 A1566412 91400 BMX320MS 5EXTA4 4 BMW X3 Car 27/09/21 27/09/21 Estate 5 1998 Petrol/PlugIn Elec Hybrid Turbo Automatic No No No