How to read a JSON with missing fields to fill in a dictionary?

Asked

Viewed 139 times

0

In Python 3 this code reads the Federal Senate API, the proposition data:

import requests
import pandas as pd

headers = {"Accept" : "application/json"}

url = 'http://legis.senado.leg.br/dadosabertos/materia/pesquisa/lista?ano=2018'

try:
    r = requests.get(url, headers=headers)
except requests.exceptions.HTTPError as errh:
    print ("Http Error:",errh)
except requests.exceptions.ConnectionError as errc:
    print ("Error Connecting:",errc) 
except requests.exceptions.Timeout as errt:
    print ("Timeout Error:",errt)
except requests.exceptions.RequestException as err:
    print ("OOps: Something Else",err)

projetos = r.json()

Example of JSON generated, first lines:

{'PesquisaBasicaMateria': {'@xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
  '@xsi:noNamespaceSchemaLocation': 'http://legis.senado.gov.br/dadosabertos/dados/PesquisaBasicaMateriav5.xsd',
  'Metadados': {'Versao': '14/01/2019 12:47:04',
   'VersaoServico': '5',
   'DataVersaoServico': '2017-02-01',
   'DescricaoDataSet': 'Efetua a pesquisa de matérias, com a criação de um filtro através dos parâmetros que podem ser informados.\n      Se não informar parâmetro algum, não retorna conteúdo.'},
  'Materias': {'Materia': [{'IdentificacaoMateria': {'CodigoMateria': '132317',
      'SiglaCasaIdentificacaoMateria': 'SF',
      'NomeCasaIdentificacaoMateria': 'Senado Federal',
      'SiglaSubtipoMateria': 'ACE',
      'DescricaoSubtipoMateria': 'AVISO DA COMISSÃO DE EDUCAÇÃO',
      'NumeroMateria': '00001',
      'AnoMateria': '2018',
      'DescricaoIdentificacaoMateria': 'ACE 1/2018',
      'IndicadorTramitando': 'Não'},
     'DadosBasicosMateria': {'EmentaMateria': 'Avalia as medidas adotadas pelo Governo Federal e pelas prefeituras municipais para implementar as estratégias do Plano Nacional de Educação no que concerne à sua Meta 1 (educação infantil), bem como as medidas adotadas pelos entes federativos para promover o funcionamento de creches e pré-escolas construídas com recursos federais por meio do Proinfância.',
      'IndicadorComplementar': 'Não',
      'DataApresentacao': '2018-02-23',
      'NaturezaMateria': {'CodigoNatureza': '304',
       'NomeNatureza': 'DECISAO_TCU',
       'DescricaoNatureza': 'Decisão do Tribunal de Contas da União'}},
     'AutoresPrincipais': {'AutorPrincipal': {'NomeAutor': 'Tribunal de Contas da União',
       'SiglaTipoAutor': 'TRIBUNAL_CONTAS_UNIAO',
       'IndicadorOutrosAutores': 'Não'}},
     'SituacaoAtual': {'Autuacoes': {'Autuacao': {'NumeroAutuacao': '1',
        'Situacao': {'DataSituacao': '2018-03-07',
         'CodigoSituacao': '107',
         'SiglaSituacao': 'CONHECIDA',
         'DescricaoSituacao': 'CONHECIDA.'},
        'Local': {'DataLocal': '2018-03-07',
         'CodigoLocal': '47',
         'SiglaCasaLocal': 'SF',
         'NomeCasaLocal': 'Senado Federal',
         'SiglaLocal': 'CE',
         'NomeLocal': 'Comissão de Educação, Cultura e Esporte'}}}}},
    {'IdentificacaoMateria': {'CodigoMateria': '133324',
      'SiglaCasaIdentificacaoMateria': 'SF',
      'NomeCasaIdentificacaoMateria': 'Senado Federal',
      'SiglaSubtipoMateria': 'ACE',
      'DescricaoSubtipoMateria': 'AVISO DA COMISSÃO DE EDUCAÇÃO',
      'NumeroMateria': '00002',
      'AnoMateria': '2018',
      'DescricaoIdentificacaoMateria': 'ACE 2/2018',
      'IndicadorTramitando': 'Não'},
     'DadosBasicosMateria': {'EmentaMateria': 'Analisa a regularidade do usufruto da isenção de contribuição para a seguridade social das entidades beneficentes de assistência social, com atuação preponderante na área de educação.',
      'IndicadorComplementar': 'Não',
      'DataApresentacao': '2018-05-18',
      'NaturezaMateria': {'CodigoNatureza': '304',
       'NomeNatureza': 'DECISAO_TCU',
       'DescricaoNatureza': 'Decisão do Tribunal de Contas da União'}},
     'AutoresPrincipais': {'AutorPrincipal': {'NomeAutor': 'Tribunal de Contas da União',
       'SiglaTipoAutor': 'TRIBUNAL_CONTAS_UNIAO',
       'IndicadorOutrosAutores': 'Não'}},
     'SituacaoAtual': {'Autuacoes': {'Autuacao': {'NumeroAutuacao': '1',
        'Situacao': {'DataSituacao': '2018-07-10',
         'CodigoSituacao': '107',
         'SiglaSituacao': 'CONHECIDA',
         'DescricaoSituacao': 'CONHECIDA.'},
        'Local': {'DataLocal': '2018-07-10',
         'CodigoLocal': '47',
         'SiglaCasaLocal': 'SF',
         'NomeCasaLocal': 'Senado Federal',
         'SiglaLocal': 'CE',
         'NomeLocal': 'Comissão de Educação, Cultura e Esporte'}}}}},

...

My intention is to read JSON and generate a dataframe with some information. The information of the propositions begins at this level: ["Pesquisabasicamateria"]["Materias"]["Materia"] I did so:

dados = []
for item in projects["PesquisaBasicaMateria"]["Materias"]["Materia"]:
    dicionario = {"AnoMateria": str(item['IdentificacaoMateria']['AnoMateria']), 
                  "CodigoMateria": str(item['IdentificacaoMateria']['CodigoMateria']), 
                  "DescricaoIdentificacaoMateria": item['IdentificacaoMateria']['DescricaoIdentificacaoMateria'], 
                  "DescricaoObjetivoProcesso": item['IdentificacaoMateria']['DescricaoObjetivoProcesso'], 
                  "DescricaoSubtipoMateria": item['IdentificacaoMateria']['DescricaoSubtipoMateria'], 
                  "IndicadorTramitando": item['IdentificacaoMateria']['IndicadorTramitando'], 
                  "NomeCasaIdentificacaoMateria": item['IdentificacaoMateria']['NomeCasaIdentificacaoMateria'], 
                  "NumeroMateria": str(item['IdentificacaoMateria']['NumeroMateria']), 
                  "DataApresentacao": item['DadosBasicosMateria']['DataApresentacao'], 
                  "DataApresentacao": item['DadosBasicosMateria']['DataApresentacao'], 
                 }
    dados.append(dicionario)

df_prop = pd.DataFrame(dados)

I made that mistake:

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-44-45e13da1fd4f> in <module>
      4                   "CodigoMateria": str(item['IdentificacaoMateria']['CodigoMateria']),
      5                   "DescricaoIdentificacaoMateria": item['IdentificacaoMateria']['DescricaoIdentificacaoMateria'],
----> 6                   "DescricaoObjetivoProcesso": item['IdentificacaoMateria']['DescricaoObjetivoProcesso'],
      7                   "DescricaoSubtipoMateria": item['IdentificacaoMateria']['DescricaoSubtipoMateria'],
      8                   "IndicadorTramitando": item['IdentificacaoMateria']['IndicadorTramitando'],

KeyError: 'DescricaoObjetivoProcesso'

The problem is that JSON does not always have the same information keys in all propositions. For example, 'Descriptionobjective' does not appear in all propositions and when it is not has null value, it is simply omitted

Please, is there a way to read JSON to fill in a dictionary in which the fields are not always present? Something like, if 'Descriptionobjective' does not exist then leave blank

1 answer

1


Before filling the dictionary with the desired key you check if the key exists in JSON. That way:

dicionario = {
    "DescricaoObjetivoProcesso": item["DescricaoObjetivoProcesso"] if "DescricaoObjetivoProcesso" in item else None
}

You add item["DescricaoObjetivoProcesso"] to the dictionary if it exists and None otherwise.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.