0

Problem:

I am having trouble pulling some info off ups. The city and state in the shipToAddress section.

Below is the data in a easy to read format that i am pulling from ups website with requests:

Data:

data = {
    'statusCode': '200',
    'statusText': 'Successful',
    'isLoggedInUser': False,
    'trackedDateTime': '04/16/2019 1:33 P.M. EST',
    'isBcdnMultiView': False,
    'trackDetails': [{
        'errorCode': None,
        'errorText': None,
        'requestedTrackingNumber': '1Z3774E8YN99957400',
        'trackingNumber': '1Z3774E8YN99957400',
        'isMobileDevice': False,
        'packageStatus': 'Loaded on Delivery Vehicle',
        'packageStatusType': 'I',
        'packageStatusCode': '072',
        'progressBarType': 'InTransit',
        'progressBarPercentage': '90',
        'simplifiedText': '',
        'scheduledDeliveryDayCMSKey': 'cms.stapp.tue',
        'scheduledDeliveryDate': '04/16/2019',
        'noEstimatedDeliveryDateLabel': None,
        'scheduledDeliveryTime': 'cms.stapp.eod',
        'scheduledDeliveryTimeEODLabel': 'cms.stapp.eod',
        'packageCommitedTime': '',
        'endOfDayResCMSKey': None,
        'deliveredDayCMSKey': '',
        'deliveredDate': '',
        'deliveredTime': '',
        'receivedBy': '',
        'leaveAt': None,
        'leftAt': '',
        'shipToAddress': {
            'streetAddress1': '',
            'streetAddress2': '',
            'streetAddress3': '',
            'city': 'OCEAN',
            'state': 'NJ',
            'province': None,
            'country': 'US',
            'zipCode': '',
            'companyName': '',
            'attentionName': '',
            'isAddressCorrected': False,
            'isReturnAddress': False,
            'isHoldAddress': False,
}}]}

Code:

data = response.text
addressinfo =json.loads(data)['trackDetails']['shipToAddress']

for entry in addressinfo:
    city = (entry['city'])  
    state = (entry['state'])
    country = (entry['country'])

My Expected Results:

city = 'Ocean'

state = 'NJ'

etc

this is error:

addressinfo =json.loads(data2)['trackDetails']['shipToAddress']

TypeError: list indices must be integers or slices, not str

duc hathaway
  • 417
  • 1
  • 4
  • 9

2 Answers2

4

Note the format of your JSON:

'trackDetails': [{
    ...
    'shipToAddress': {...}
}]

The dict you're trying to index into is actually contained inside of a list (note the square brackets). The proper way to access the shipToAddress field would be to do this:

addressinfo = json.loads(data2)['trackDetails'][0]['shipToAddress']
                                               ^^^

instead of what you were doing.

Green Cloak Guy
  • 23,793
  • 4
  • 33
  • 53
  • alright that makes alot of sense, thank you for explaining my oversight – duc hathaway Apr 16 '19 at 18:31
  • @green-cload-guy if there were multiple shipToAddress sections would there be anyway to pull all of them or would i need to specify the first one like in your answer above? – duc hathaway Apr 16 '19 at 18:50
  • See [this answer](https://stackoverflow.com/questions/5306741/do-json-keys-need-to-be-unique) for JSON key uniqueness in general - according to the JSON RFC, [keys should be unique](http://www.ietf.org/rfc/rfc4627.txt), so you should never see `'shipToAddress'` as the same key in the same field, and I'm not sure how python would handle that behavior (probably with an [`OrderedDict`](https://docs.python.org/2/library/collections.html#collections.OrderedDict)). – Green Cloak Guy Apr 16 '19 at 19:42
  • 1
    Though if there were multiple sets of track details, you could iterate through the list and take `shipToAddress` from each one, e.g. `d['shipToAddress'] for d in json.loads(data2)['trackDetails']`. – Green Cloak Guy Apr 16 '19 at 19:43
1

When you return data = response.text you should instead do data = response.json() since it is a json. This will allow you to access it like a json. Instead you are converting it to a string with .text and then attempting to load it back in which is not necessary.

Then access city:

city = data['trackDetails'][0]['shipToAddress']['city']
state = data['trackDetails'][0]['shipToAddress']['state']
MyNameIsCaleb
  • 4,409
  • 1
  • 13
  • 31