使用API​​数据创建字典时出错 - 字符串索引必须是整数

时间:2017-12-18 17:39:51

标签: json python-3.x

在Python3中,我创建了一个程序来读取API(来自巴西众议院)并以JSON格式获取数据:

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

# first create a dictionary with the names and links of each deputy
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']:
        deputados[deputado['nome']] = deputado['uri']

# then read each link and create a dictionary with the data of each deputy
perfis = {}
for chave, valor in deputados.items():
    print(valor)
    print(chave)
    resposta = requests.get(valor)
    for linha in resposta.json()['dados']:
        perfis[chave] = linha['uri']
        perfis[chave]= linha['nomeCivil']
    for linha2 in resposta.json()['ultimoStatus']:
        perfis[chave] = linha2['nomeEleitoral']
        perfis[chave] = linha2['siglaPartido']
        perfis[chave] = linha2['siglaUf']
        perfis[chave]= linha2['urlFoto']
    for linha3 in resposta.json()['ultimoStatus/gabinete']:
        perfis[chave] = linha3['telefone']
        perfis[chave] = linha3['email']
        perfis[chave] = linha3['sexo']
        perfis[chave] = linha3['dataNascimento']

但我收到此错误消息:

https://dadosabertos.camara.leg.br/api/v2/deputados/178957
ABEL MESQUITA JR.

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-49-067597090c77> in <module>()
      5     resposta = requests.get(valor)
      6     for linha in resposta.json()['dados']:
----> 7         perfis[chave] = linha['uri']
      8         perfis[chave]= linha['nomeCivil']
      9     for linha2 in resposta.json()['ultimoStatus']:

TypeError: string indices must be integers

以下是页面数据的示例:

resposta = requests.get('https://dadosabertos.camara.leg.br/api/v2/deputados/178957')
print(resposta.json())
{'dados': {'id': 178957, 'uri': 'https://dadosabertos.camara.leg.br/api/v2/deputados/178957', 'nomeCivil': 'ABEL SALVADOR MESQUITA JUNIOR', 'ultimoStatus': {'id': 178957, 'uri': 'https://dadosabertos.camara.leg.br/api/v2/deputados/178957', 'nome': 'ABEL MESQUITA JR.', 'siglaPartido': 'DEM', 'uriPartido': 'https://dadosabertos.camara.leg.br/api/v2/partidos/36769', 'siglaUf': 'RR', 'idLegislatura': 55, 'urlFoto': 'http://www.camara.leg.br/internet/deputado/bandep/178957.jpg', 'data': '2015-02-01', 'nomeEleitoral': 'ABEL MESQUITA JR.', 'gabinete': {'nome': '248', 'predio': '4', 'sala': '248', 'andar': '2', 'telefone': '3215-5248', 'email': 'dep.abelmesquitajr.@camara.leg.br'}, 'situacao': 'Exercício', 'condicaoEleitoral': 'Titular', 'descricaoStatus': None}, 'cpf': '', 'sexo': 'M', 'urlWebsite': None, 'redeSocial': [], 'dataNascimento': '1962-03-29', 'dataFalecimento': None, 'ufNascimento': 'RR', 'municipioNascimento': 'Boa Vista', 'escolaridade': 'Superior Incompleto'}, 'links': [{'rel': 'self', 'href': 'https://dadosabertos.camara.leg.br/api/v2/deputados/178957'}]}

请问,有没有人知道为什么在创建第二个字典并开始提供它时发生了错误?

2 个答案:

答案 0 :(得分:1)

当您遍历字典(resposta.json()['dados'])时,默认迭代字典的。因此linha将为iduri等。这就是您获得string indices must be integers的原因。我很难理解你要做什么,因为它不是英文的,但如果你只是想从json字典中提取信息,你可能想要这样做:

json_res = reposta.json()
perfis.update(json_res['dados'])
perfis.update(json_res['ultimoStatus'])

答案 1 :(得分:1)

使用The type 'string' must be a non-nullable value in order to use it as a parameter 'T' in the generic type or method 'Nullable<T>'.循环,您正在访问字典中的每个键(这是一个字符串),并使用另一个字符串索引该字符串:基本上,您正在调用//gallery and upload buttons: @Override public void onClick(View v) { switch (v.getId()) { case R.id.imageToUpload: if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) { String[] permissions = {Manifest.permission.READ_EXTERNAL_STORAGE}; requestPermissions(permissions, PERMISSION_REQUEST_CODE); } } Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(galleryIntent, RESULT_LOAD_IMAGE); break; case R.id.bUploadImage: bUploadImage.setEnabled(false); Bitmap image = null; if(hasImage(imageToUpload)) { image = ((BitmapDrawable) imageToUpload.getDrawable()).getBitmap(); } else{ if(uploadImageName.length() < 2){ // no image and no text bUploadImage.setEnabled(true); return; } } new UploadImage(image, uploadImageName.getText().toString()); break; } super.onClick(v); //to baseactivity profile click work. } 。< / p>

您可以避免private class UploadImage { Bitmap image; String name; String encodedImage = ""; UploadImage(Bitmap image, String name) { this.image = image; this.name = name; if(image != null) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream); encodedImage = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT); } Response.Listener<String> responseListener = new Response.Listener<String>(){ @Override public void onResponse(String response){ try { JSONObject jsonResponse = new JSONObject(response); boolean success = jsonResponse.getBoolean("success"); if(success){ String done = getResources().getString(R.string.done); Toast.makeText(getApplicationContext(), done, Toast.LENGTH_SHORT).show(); } else{ AlertDialog.Builder builder = new AlertDialog.Builder(Upload.this); String error = getResources().getString(R.string.error); String retry = getResources().getString(R.string.retry); builder.setMessage(error) .setNegativeButton(retry,null) .create() .show(); } } catch (JSONException e){ e.printStackTrace(); } } }; UploadRequest uploadRequest = new UploadRequest(encodedImage, UserId, name, token, responseListener); RequestQueue queue = Volley.newRequestQueue(Upload.this); queue.add(uploadRequest); } } 循环并直接访问您的变量;这样的事情应该有效:

for