python - Python - 读取 JSON - TypeError:字符串索引必须是整数
问题描述
我正在尝试读取我自己在脚本中创建的 json。当我在阅读以下错误后尝试访问他的“属性”之一时:
Traceback (most recent call last):
File "index.py", line 74, in <module>
print(json_leitura['items'])
TypeError: string indices must be integers
当我把它 print(json_leitura['topico'])
放在最后时也会发生同样的错误。
不知道JSON文件的创建是否正确。我不知道阅读是否正确。当我尝试触发“打印”命令或将值分配给变量时。上述错误总是发生。
代码
import requests
import json
def requisicao_api(url):
resposta = requests.get(url)
if resposta.status_code == 200:
return resposta.json()
else:
return resposta.status_code
def requisicao_url(url):
dados_api = requisicao_api(url)
return dados_api
def monta_lista_repos_topico(topico):
lista_registros = []
# Percorre os 1000 primeiros registros, ou seja, 10 páginas de 100 registros.
for x in range(1,2):
urlprincipal = f'https://api.github.com/search/repositories?q=topic:{str(topico)}&sort=stars&order=desc&page={str(x)}&per_page=1'
print(urlprincipal)
dados_api = requisicao_url(urlprincipal)
if type(dados_api) is int: # Caso ocorra algum erro. Sai do loop e retorna lista vazia
print("Erro: " + str(dados_api))
break
else:
#Pega os repositórios no item e insere em uma lista
print("Página: " + str(x))
print(dados_api['items'])
items = dados_api['items']
for i in range(len(items)):
lista_registros.append(items[i])
return(lista_registros)
def gravar_arquivo_json(nome_arquivo, dados):
with open(nome_arquivo, 'w', encoding='utf-8') as f:
json.dump(dados, f, ensure_ascii=False, indent=2, sort_keys=False, separators=(',' , ':'))
def ler_arquivo_json(nome_arquivo):
with open(nome_arquivo, 'r', encoding='utf8') as f:
return json.load(f)
#================================================================================#
# MAIN #
#================================================================================#
# Alterar essas duas variáveis
topico = "open-data"
nome_arquivo = "open-data.json"
# Monta uma lista com os repositórios do tópico
lista_repos = monta_lista_repos_topico(topico)
# Monta um json com tópico e lista de repositórios
registro_json = {}
registro_json['topico'] = topico
registro_json['items'] = lista_repos
arquivo_json = json.dumps(registro_json, indent=2, sort_keys=False)
print(arquivo_json)
# Grava json
gravar_arquivo_json(nome_arquivo, arquivo_json)
# Leitura json
json_leitura = ler_arquivo_json(nome_arquivo)
print(json_leitura['items'])
JSON
"{\n \"topico\": \"open-data\",\n \"items\": [\n {\n \"id\": 62087567,\n \"node_id\": \"MDEwOlJlcG9zaXRvcnk2MjA4NzU2Nw==\",\n \"name\": \"serenata-de-amor\",\n \"full_name\": \"okfn-brasil/serenata-de-amor\",\n \"private\": false,\n \"owner\": {\n \"login\": \"okfn-brasil\",\n \"id\": 1666382,\n \"node_id\": \"MDEyOk9yZ2FuaXphdGlvbjE2NjYzODI=\",\n \"avatar_url\": \"https://avatars.githubusercontent.com/u/1666382?v=4\",\n \"gravatar_id\": \"\",\n \"url\": \"https://api.github.com/users/okfn-brasil\",\n \"html_url\": \"https://github.com/okfn-brasil\",\n \"followers_url\": \"https://api.github.com/users/okfn-brasil/followers\",\n \"following_url\": \"https://api.github.com/users/okfn-brasil/following{/other_user}\",\n \"gists_url\": \"https://api.github.com/users/okfn-brasil/gists{/gist_id}\",\n \"starred_url\": \"https://api.github.com/users/okfn-brasil/starred{/owner}{/repo}\",\n \"subscriptions_url\": \"https://api.github.com/users/okfn-brasil/subscriptions\",\n \"organizations_url\": \"https://api.github.com/users/okfn-brasil/orgs\",\n \"repos_url\": \"https://api.github.com/users/okfn-brasil/repos\",\n \"events_url\": \"https://api.github.com/users/okfn-brasil/events{/privacy}\",\n \"received_events_url\": \"https://api.github.com/users/okfn-brasil/received_events\",\n \"type\": \"Organization\",\n \"site_admin\": false\n },\n \"html_url\": \"https://github.com/okfn-brasil/serenata-de-amor\",\n \"description\": \"\\ud83d\\udd75 Artificial Intelligence for social control of public administration\",\n \"fork\": false,\n \"url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor\",\n \"forks_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/forks\",\n \"keys_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/keys{/key_id}\",\n \"collaborators_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/collaborators{/collaborator}\",\n \"teams_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/teams\",\n \"hooks_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/hooks\",\n \"issue_events_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/issues/events{/number}\",\n \"events_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/events\",\n \"assignees_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/assignees{/user}\",\n \"branches_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/branches{/branch}\",\n \"tags_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/tags\",\n \"blobs_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/git/blobs{/sha}\",\n \"git_tags_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/git/tags{/sha}\",\n \"git_refs_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/git/refs{/sha}\",\n \"trees_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/git/trees{/sha}\",\n \"statuses_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/statuses/{sha}\",\n \"languages_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/languages\",\n \"stargazers_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/stargazers\",\n \"contributors_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/contributors\",\n \"subscribers_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/subscribers\",\n \"subscription_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/subscription\",\n \"commits_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/commits{/sha}\",\n \"git_commits_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/git/commits{/sha}\",\n \"comments_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/comments{/number}\",\n \"issue_comment_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/issues/comments{/number}\",\n \"contents_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/contents/{+path}\",\n \"compare_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/compare/{base}...{head}\",\n \"merges_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/merges\",\n \"archive_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/{archive_format}{/ref}\",\n \"downloads_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/downloads\",\n \"issues_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/issues{/number}\",\n \"pulls_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/pulls{/number}\",\n \"milestones_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/milestones{/number}\",\n \"notifications_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/notifications{?since,all,participating}\",\n \"labels_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/labels{/name}\",\n \"releases_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/releases{/id}\",\n \"deployments_url\": \"https://api.github.com/repos/okfn-brasil/serenata-de-amor/deployments\",\n \"created_at\": \"2016-06-27T20:55:11Z\",\n \"updated_at\": \"2021-06-03T02:10:38Z\",\n \"pushed_at\": \"2021-06-01T17:54:22Z\",\n \"git_url\": \"git://github.com/okfn-brasil/serenata-de-amor.git\",\n \"ssh_url\": \"git@github.com:okfn-brasil/serenata-de-amor.git\",\n \"clone_url\": \"https://github.com/okfn-brasil/serenata-de-amor.git\",\n \"svn_url\": \"https://github.com/okfn-brasil/serenata-de-amor\",\n \"homepage\": \"https://serenata.ai/en\",\n \"size\": 71008,\n \"stargazers_count\": 4283,\n \"watchers_count\": 4283,\n \"language\": \"Python\",\n \"has_issues\": true,\n \"has_projects\": false,\n \"has_downloads\": true,\n \"has_wiki\": false,\n \"has_pages\": false,\n \"forks_count\": 696,\n \"mirror_url\": null,\n \"archived\": false,\n \"disabled\": false,\n \"open_issues_count\": 66,\n \"license\": {\n \"key\": \"mit\",\n \"name\": \"MIT License\",\n \"spdx_id\": \"MIT\",\n \"url\": \"https://api.github.com/licenses/mit\",\n \"node_id\": \"MDc6TGljZW5zZTEz\"\n },\n \"forks\": 696,\n \"open_issues\": 66,\n \"watchers\": 4283,\n \"default_branch\": \"main\",\n \"score\": 1.0\n }\n ]\n}"
解决方案
问题出在一线
arquivo_json = json.dumps(registro_json, indent=2, sort_keys=False)
根据文档,json.dumps
“根据转换表将 obj 序列化为 JSON 格式的 str ”
实际上,问题在于您将registro_json
对象序列化两次,并以str
. 如果您删除有问题的行并直接传递registro_json
给该gravar_arquivo_json
函数,则一切正常。
更新代码:
import requests
import json
def requisicao_api(url):
resposta = requests.get(url)
if resposta.status_code == 200:
return resposta.json()
else:
return resposta.status_code
def requisicao_url(url):
dados_api = requisicao_api(url)
return dados_api
def monta_lista_repos_topico(topico):
lista_registros = []
# Percorre os 1000 primeiros registros, ou seja, 10 páginas de 100 registros.
for x in range(1,2):
urlprincipal = f'https://api.github.com/search/repositories?q=topic:{str(topico)}&sort=stars&order=desc&page={str(x)}&per_page=1'
print(urlprincipal)
dados_api = requisicao_url(urlprincipal)
if type(dados_api) is int: # Caso ocorra algum erro. Sai do loop e retorna lista vazia
print("Erro: " + str(dados_api))
break
else:
#Pega os repositórios no item e insere em uma lista
print("Página: " + str(x))
print(dados_api['items'])
items = dados_api['items']
for i in range(len(items)):
lista_registros.append(items[i])
return(lista_registros)
def gravar_arquivo_json(nome_arquivo, dados):
with open(nome_arquivo, 'w', encoding='utf-8') as f:
json.dump(dados, f, ensure_ascii=False, indent=2, sort_keys=False, separators=(',' , ':'))
def ler_arquivo_json(nome_arquivo):
with open(nome_arquivo, 'r', encoding='utf8') as f:
return json.load(f)
#================================================================================#
# MAIN #
#================================================================================#
# Alterar essas duas variáveis
topico = "open-data"
nome_arquivo = "open-data.json"
# Monta uma lista com os repositórios do tópico
lista_repos = monta_lista_repos_topico(topico)
# Monta um json com tópico e lista de repositórios
registro_json = {}
registro_json['topico'] = topico
registro_json['items'] = lista_repos
# Grava json
gravar_arquivo_json(nome_arquivo, registro_json)
# Leitura json
json_leitura = ler_arquivo_json(nome_arquivo)
print(json_leitura['items'])