2

In Python3 I made a program to read an API (from Brazilian Chamber of Deputies) and get the data in JSON

import requests
import pandas as pd

url = 'https://dadosabertos.camara.leg.br/api/v2/deputados'

First I made a list with dictionaries - they are the names of the deputies and the respective API link of each. The parameters were json, number of items per page and page number (there are more than 500 deputies, then there are six pages)

deputados = []
for pagina in [1, 2, 3, 4, 5, 6]:
    parametros = {'formato': 'json', 'itens': 100, 'pagina': pagina}
    resposta = requests.get(url, parametros)
    for deputado in resposta.json()['dados']:
        dicionario = {"deputado": deputado['nome'], "link_api": deputado['uri']}
        deputados.append(dicionario)

Content of the list:

deputados
[{'deputado': 'ABEL MESQUITA JR.',
  'link_api': 'https://dadosabertos.camara.leg.br/api/v2/deputados/178957'},
 {'deputado': 'ADAIL CARNEIRO',
  'link_api': 'https://dadosabertos.camara.leg.br/api/v2/deputados/178864'},
 {'deputado': 'ADALBERTO CAVALCANTI',
  'link_api': 'https://dadosabertos.camara.leg.br/api/v2/deputados/178914'},
 {'deputado': 'ADELMO CARNEIRO LEÃO',
  'link_api': 'https://dadosabertos.camara.leg.br/api/v2/deputados/178890'},
 {'deputado': 'ADELSON BARRETO',
  'link_api': 'https://dadosabertos.camara.leg.br/api/v2/deputados/178968'},
 {'deputado': 'ADEMIR CAMILO',
  'link_api': 'https://dadosabertos.camara.leg.br/api/v2/deputados/133374'},
...

I create a dataframe with the result

df = pd.DataFrame(deputados)
df.reset_index().head()
index   deputado    link_api
0   0   ABEL MESQUITA JR.   https://dadosabertos.camara.leg.br/api/v2/depu...
1   1   ADAIL CARNEIRO  https://dadosabertos.camara.leg.br/api/v2/depu...
2   2   ADALBERTO CAVALCANTI    https://dadosabertos.camara.leg.br/api/v2/depu...
3   3   ADELMO CARNEIRO LEÃO    https://dadosabertos.camara.leg.br/api/v2/depu...
4   4   ADELSON BARRETO     https://dadosabertos.camara.leg.br/api/v2/depu...

Then I created another list with dictionaries. This time I want to go on every deputy API page and extract some of the data. I put some prints to check the results ("resposta" and "linha"). Parameter now is just json

perfis = []
for num, row in df.iterrows():
    parametros = {'formato': 'json'}
    resposta = requests.get(row['link_api'], parametros)
    print(resposta)
    for linha in resposta.json()['dados']:
        print(linha)
        item1 = linha['uri']
        item2 = linha['nomeCivil']
    for linha2 in resposta.json()['ultimoStatus']:
        item3 = linha2['nomeEleitoral']
        item4 = linha2['siglaPartido']
        item5 = linha2['siglaUf']
        item6 = linha2['urlFoto']
    for linha3 in resposta.json()['ultimoStatus/gabinete']:
        item7 = linha3['telefone']
        item8 = linha3['email']
        item9 = linha3['sexo']
        item10 = linha3['dataNascimento']
    dicionario = {"link_api": item1, "nome_completo": item2, "nome_eleitoral": item3, "partido": item4, "uf": item5, "link_foto": item6, "telefone": item7, "e_mail": item8, "sexo": item9, "data_nascimento": item2}    
    perfis.append(dicionario)

Here I had an error (string indices must be integers) and the prints showed that the deputy API was not read correctly

<Response [200]>
id

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-21-bfada3632dc2> in <module>()
      6     for linha in resposta.json()['dados']:
      7         print(linha)
----> 8         item1 = linha['uri']
      9         item2 = linha['nomeCivil']
     10     for linha2 in resposta.json()['ultimoStatus']:

TypeError: string indices must be integers

Just confirming, the "resposta" print was = Response [200] and the "linha" = id. In the "resposta" case should have the requests.get value of the API link. And "linha" is the json value of the chosen item

Then I individually tested an API link and it worked:

resposta = requests.get('https://dadosabertos.camara.leg.br/api/v2/deputados/178890')
print(resposta.json())
{'dados': {'id': 178890, 'uri': 'https://dadosabertos.camara.leg.br/api/v2/deputados/178890', 'nomeCivil': 'ADELMO CARNEIRO LEAO', 'ultimoStatus': {'id': 178890, 'uri': 'https://dadosabertos.camara.leg.br/api/v2/deputados/178890', 'nome': 'ADELMO CARNEIRO LEÃO', 'siglaPartido': 'PT', 'uriPartido': 'https://dadosabertos.camara.leg.br/api/v2/partidos/36844', 'siglaUf': 'MG', 'idLegislatura': 55, 'urlFoto': 'http://www.camara.leg.br/internet/deputado/bandep/178890.jpg', 'data': '2015-03-06', 'nomeEleitoral': 'ADELMO CARNEIRO LEÃO', 'gabinete': {'nome': '231', 'predio': '4', 'sala': '231', 'andar': '2', 'telefone': '3215-5231', 'email': '[email protected]'}, 'situacao': 'Exercício', 'condicaoEleitoral': 'Suplente', 'descricaoStatus': None}, 'cpf': '', 'sexo': 'M', 'urlWebsite': None, 'redeSocial': [], 'dataNascimento': '1949-05-25', 'dataFalecimento': None, 'ufNascimento': 'MG', 'municipioNascimento': 'Itapagipe', 'escolaridade': 'Doutorado'}, 'links': [{'rel': 'self', 'href': 'https://dadosabertos.camara.leg.br/api/v2/deputados/178890'}]}

​The JSON page can be seen here: https://dadosabertos.camara.leg.br/api/v2/deputados/178890?formato=json

Please can this mean that some parameter is missing when I try to create the second list?

4
  • 1
    resposta.json()['dados'] is obviously a dictionary so when you iterate over it with a for..in loop you're essentially getting its keys, not its values. Add .values() at the end to iterate over the values. Commented Dec 19, 2017 at 14:44
  • Maybe not all of the api links provide uri? Commented Dec 19, 2017 at 14:47
  • Hello, thanks. I've put -> for linha in resposta.json () ['data']. values (): Commented Dec 19, 2017 at 14:59
  • but the "resposta" print continues Response [200]. and the "linha" print shows 178957, which is the id value Commented Dec 19, 2017 at 14:59

1 Answer 1

1

Because of this line:

for linha in resposta.json()['dados']:

Here is an example of what you have in resposta.json()['dados']:

{'ufNascimento': 'MG', 'municipioNascimento': 'Teófilo Otoni', 'redeSocial': [], 'id': 133374, 'dataNascimento': '1964-05-30', 'dataFalecimento': None, 'urlWebsite': None, 'ultimoStatus': {'siglaPartido': 'PODE', 'condicaoEleitoral': 'Suplente', 'idLegislatura': 55, 'nome': 'ADEMIR CAMILO', 'id': 133374, 'nomeEleitoral': 'ADEMIR CAMILO', 'descricaoStatus': None, 'uri': 'https://dadosabertos.camara.leg.br/api/v2/deputados/133374', 'uriPartido': 'https://dadosabertos.camara.leg.br/api/v2/partidos/36896', 'situacao': 'Exercício', 'urlFoto': 'http://www.camara.leg.br/internet/deputado/bandep/133374.jpg', 'gabinete': {'predio': '4', 'nome': '556', 'andar': '5', 'sala': '556', 'telefone': '3215-5556', 'email': '[email protected]'}, 'siglaUf': 'MG', 'data': '2016-04-19'}, 'nomeCivil': 'ADEMIR CAMILO PRATES RODRIGUES', 'cpf': '', 'escolaridade': None, 'sexo': 'M', 'uri': 'https://dadosabertos.camara.leg.br/api/v2/deputados/133374'}

It's a dictionary.

for x in dictonary loops in dictionary's keys, so you are looping on a list:

['urlWebsite', 'sexo', 'nomeCivil', 'cpf', 'ultimoStatus', 'dataFalecimento', 'municipioNascimento', 'uri', 'id', 'escolaridade', 'dataNascimento', 'redeSocial', 'ufNascimento']

So, writing item1 = linha['uri'] it's like writing item1 = ['foo', 'bar']['baz'] which obviously does not means anything.

Quick fix: replace for linha in resposta.json()['dados']: by linha = resposta.json()['dados'] and unindent following code. It would works

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much. The command (linha = resposta.json()['dados']) worked fine. But when I try to get the dictionary inside 'dados' it does not work (linha2 = resposta.json()['dados/ultimoStatus']). It has this error: KeyError: KeyError: 'dados/ultimoStatus'
In order to access one dictionary within another, should the command be another?
You cannot do a_dict['foo/bar'] to access key foo > bar. What you want is linha2 = resposta.json()['dados']['ultimoStatus']

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.