首页 > 解决方案 > How to extract JSON content with requests from an API?

问题描述

In Python 3 I want to access an API from a Brazilian public service: http://legis.senado.leg.br/dadosabertos/docs/ui/index.html#/PesquisaMateriaService

The documentation also mentions that the content may come in application / json: http://legis.senado.leg.br/dadosabertos/docs/resource_PesquisaMateriaService.html#resource_PesquisaMateriaService_materiaListaPesquisa_GET

My intention is to access with requests and then generate a JSON. I ran a test with a "ano" filter

import requests

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

try:
    r = requests.get(url)
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)

projects = r.json()

But this error message appeared:

---------------------------------------------------------------------------
JSONDecodeError                           Traceback (most recent call last)
<ipython-input-2-aa958e05ad1d> in <module>
     12     print ("OOps: Something Else",err)
     13 
---> 14 projects = r.json()

~/Documentos/Code/apis/lib/python3.6/site-packages/requests/models.py in json(self, **kwargs)
    895                     # used.
    896                     pass
--> 897         return complexjson.loads(self.text, **kwargs)
    898 
    899     @property

/usr/lib/python3.6/json/__init__.py in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    352             parse_int is None and parse_float is None and
    353             parse_constant is None and object_pairs_hook is None and not kw):
--> 354         return _default_decoder.decode(s)
    355     if cls is None:
    356         cls = JSONDecoder

/usr/lib/python3.6/json/decoder.py in decode(self, s, _w)
    337 
    338         """
--> 339         obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    340         end = _w(s, end).end()
    341         if end != len(s):

/usr/lib/python3.6/json/decoder.py in raw_decode(self, s, idx)
    355             obj, end = self.scan_once(s, idx)
    356         except StopIteration as err:
--> 357             raise JSONDecodeError("Expecting value", s, err.value) from None
    358         return obj, end

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

I looked at the contents of "r" and what appears is an XML. Some of the content:

r.content

b'<?xml version = \'1.0\' encoding=\'UTF-8\'?>\n<PesquisaBasicaMateria xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://legis.senado.gov.br/dadosabertos/dados/PesquisaBasicaMateriav5.xsd">\n   <Metadados>\n      <Versao>11/01/2019 17:27:18</Versao><VersaoServico>5</VersaoServico><DataVersaoServico>2017-02-01</DataVersaoServico><DescricaoDataSet>Efetua a pesquisa de mat\xc3\xa9rias, com a cria\xc3\xa7\xc3\xa3o de um filtro atrav\xc3\xa9s dos par\xc3\xa2metros que podem ser informados.\n      Se n\xc3\xa3o informar par\xc3\xa2metro algum, n\xc3\xa3o retorna conte\xc3\xbado.</DescricaoDataSet>\n   </Metadados>\n   <Materias>\n      <Materia><IdentificacaoMateria><CodigoMateria>132317</CodigoMateria><SiglaCasaIdentificacaoMateria>SF</SiglaCasaIdentificacaoMateria><NomeCasaIdentificacaoMateria>Senado Federal</NomeCasaIdentificacaoMateria><SiglaSubtipoMateria>ACE</SiglaSubtipoMateria><DescricaoSubtipoMateria>AVISO DA COMISS\xc3\x83O DE EDUCA\xc3\x87\xc3\x83O</DescricaoSubtipoMateria><NumeroMateria>00001</NumeroMateria><AnoMateria>2018</AnoMateria>

Please, is there a way to access the content in JSON?

标签: pythonjsonxmlpython-requests

解决方案


查看 Swagger API 文档。您需要设置以下 HTTP 标头:

headers = {"Accept" : "application/json"}
r = requests.get(url, headers=headers)

推荐阅读