Maciej
Maciej

Reputation: 65

Error processing JSON downloaded using 'http' - TypeError: string indices must be integers

I am trying to retrieve some data from API and put it into database but I have faced some problems.

API Data: https://api.coronatracker.com/v4/analytics/newcases/country?countryCode=PL&startDate=2020-11-01&endDate=2020-11-06

Data from above URL

[
  {"country":"Poland","country_code":"PL","last_updated":"2020-11-02T00:01:00.000Z","new_deaths":92,"new_infections":15578,"new_recovered":7818},
  {"country":"Poland","country_code":"PL","last_updated":"2020-11-03T00:02:00.000Z","new_deaths":227,"new_infections":19364,"new_recovered":5573},
  {"country":"Poland","country_code":"PL","last_updated":"2020-11-04T00:00:00.000Z","new_deaths":373,"new_infections":24692,"new_recovered":8974},
  {"country":"Poland","country_code":"PL","last_updated":"2020-11-05T00:11:00.000Z","new_deaths":367,"new_infections":27143,"new_recovered":8721}
]

Error

Date = i['last_updated'] TypeError: string indices must be integers

Part of my code

try:
    response = http.request('GET', url)
    data = json.loads(response.data.decode('utf-8'))
    index = 0

    for i in data:
        Date = None
        Confirmed = None
        Deaths = None
        Recovered = None
        #Active = None

        Date = i['last_updated']
        Confirmed = i['new_infections']
        Deaths = i['new_deaths']
        Recovered = i['new_recovered']
        #Active = i['Active']

        cur.execute("""
            INSERT INTO covid_stats_poland
            VALUES (%s, %s, %s, %s, %s); 
            """,
            (index, Date, Confirmed, Deaths, Recovered))
        conn.commit()
        index += 1
    cur.close()

Can someone please explain what am I doing wrong / how I can fix it?

Upvotes: 2

Views: 55

Answers (1)

Christopher Peisert
Christopher Peisert

Reputation: 24134

The error is most likely due to the data containing additional HTTP information, such as headers. See below for two standard approaches for retrieving JSON.

Option 1: urllib.request

import json
import urllib.request 

URL = "https://api.coronatracker.com/v4/analytics/newcases/country?countryCode=PL&startDate=2020-11-01&endDate=2020-11-06"

with urllib.request.urlopen(URL) as url:
    data = json.loads(url.read().decode())
    print(data)

for i in data:
    Date = i['last_updated']
    Confirmed = i['new_infections']
    Deaths = i['new_deaths']
    Recovered = i['new_recovered']

    print(f"\nDate: {Date}")
    print(f"Confirmed: {Confirmed}")
    print(f"Deaths: {Deaths}")
    print(f"Recovered: {Recovered}")

Output

[{'country': 'Poland', 'country_code': 'PL', 'last_updated': '2020-11-02T00:01:00.000Z', 'new_deaths': 92, 'new_infections': 15578, 'new_recovered': 7818}, {'country': 'Poland', 'country_code': 'PL', 'last_updated': '2020-11-03T00:02:00.000Z', 'new_deaths': 227, 'new_infections': 19364, 'new_recovered': 5573}, {'country': 'Poland', 'country_code': 'PL', 'last_updated': '2020-11-04T00:00:00.000Z', 'new_deaths': 373, 'new_infections': 24692, 'new_recovered': 8974}, {'country': 'Poland', 'country_code': 'PL', 'last_updated': '2020-11-05T00:11:00.000Z', 'new_deaths': 367, 'new_infections': 27143, 'new_recovered': 8721}]

Date: 2020-11-02T00:01:00.000Z
Confirmed: 15578
Deaths: 92
Recovered: 7818

Date: 2020-11-03T00:02:00.000Z
Confirmed: 19364
Deaths: 227
Recovered: 5573

Date: 2020-11-04T00:00:00.000Z
Confirmed: 24692
Deaths: 373
Recovered: 8974

Date: 2020-11-05T00:11:00.000Z
Confirmed: 27143
Deaths: 367
Recovered: 8721

Option 2: http module (less common)

import http
import json

URL = "api.coronatracker.com"
url_path = "/v4/analytics/newcases/country?countryCode=PL&startDate=2020-11-01&endDate=2020-11-06"

conn = http.client.HTTPSConnection(URL)
conn.request("GET", url_path)
response = conn.getresponse()
data = json.loads(response.read().decode())
print(data)

for i in data:
    Date = i['last_updated']
    Confirmed = i['new_infections']
    Deaths = i['new_deaths']
    Recovered = i['new_recovered']

    print(f"\nDate: {Date}")
    print(f"Confirmed: {Confirmed}")
    print(f"Deaths: {Deaths}")
    print(f"Recovered: {Recovered}")

Output

[{'country': 'Poland', 'country_code': 'PL', 'last_updated': '2020-11-02T00:01:00.000Z', 'new_deaths': 92, 'new_infections': 15578, 'new_recovered': 7818}, {'country': 'Poland', 'country_code': 'PL', 'last_updated': '2020-11-03T00:02:00.000Z', 'new_deaths': 227, 'new_infections': 19364, 'new_recovered': 5573}, {'country': 'Poland', 'country_code': 'PL', 'last_updated': '2020-11-04T00:00:00.000Z', 'new_deaths': 373, 'new_infections': 24692, 'new_recovered': 8974}, {'country': 'Poland', 'country_code': 'PL', 'last_updated': '2020-11-05T00:11:00.000Z', 'new_deaths': 367, 'new_infections': 27143, 'new_recovered': 8721}]

Date: 2020-11-02T00:01:00.000Z
Confirmed: 15578
Deaths: 92
Recovered: 7818

Date: 2020-11-03T00:02:00.000Z
Confirmed: 19364
Deaths: 227
Recovered: 5573

Date: 2020-11-04T00:00:00.000Z
Confirmed: 24692
Deaths: 373
Recovered: 8974

Date: 2020-11-05T00:11:00.000Z
Confirmed: 27143
Deaths: 367
Recovered: 8721

Upvotes: 3

Related Questions