Python调用API写入CSV时遇TypeError:string indices must be integers错误求助
问题:访问Star Wars API提取数据写入CSV时触发TypeError
运行Python代码访问Star Wars API提取指定字段写入CSV时,持续遇到以下错误:
name = item['name'] TypeError: string indices must be integers, not 'str'
错误发生在get_info函数的第一个循环行附近。相关出错代码如下:
import requests import csv from pprint import pprint as pp aHeader = ['name', 'birth_year', 'height', 'mass'] with open('star_wars_people2.csv', 'w') as file: file = csv.DictWriter(file, fieldnames=aHeader) file.writeheader() def get_info(): for item in data: name = item['name'] birth_year = item['birth_year'] height = item['height'] mass = item['mass'] with open('star_wars_people2.csv', 'a') as aFile: aFile.write(name + birth_year + height + mass + "\n") for i in range(5): user_input = input("Pick a number between 1 and 83 to find the associated Star Wars character: ") endpoint2 = 'https://swapi.dev/api/people/{}/'.format(user_input) response = requests.get(endpoint2) data = response.json() pp(data) user_input2 = input("Would you like to add this info to a file? ") if user_input2 == 'y' or 'Y': get_info() else: print('No problem!')
我是编程新手,注意到调用完整API列表时,以下代码可以成功提取单个元素,但不知道怎么适配到单条数据提取多字段的场景:
endpoint1 = 'https://swapi.dev/api/people/' response = requests.get(endpoint1) data = response.json() pp(data) aHeader = ['name', 'birth_year', 'height', 'mass'] with open('star_wars_people2.csv', 'w') as file: file = csv.DictWriter(file, fieldnames=aHeader) file.writeheader() # def get_info(): for item in data['results']: with open('star_wars_people2.csv', 'a') as aFile: aFile.write(item['name'] + "\n")
问题原因与解决方案
错误根源:请求单条人物数据(
/api/people/{id}/)时,response.json()返回的是单个字典对象,而非包含多个字典的列表。但你在get_info函数里用for item in data循环,会把字典的键名(字符串类型)遍历出来(比如'name'、'birth_year'),再尝试用item['name']访问字符串的索引,自然触发"string indices must be integers"错误。修复步骤:
- 去掉
get_info里的循环,直接用data字典提取字段 - 用
csv.DictWriter的writerow方法写入数据,避免手动拼接字符串破坏CSV格式(比如字段含逗号) - 修正条件判断逻辑:原
if user_input2 == 'y' or 'Y'等价于if (user_input2 == 'y') or True,永远为真,应改为if user_input2.lower() == 'y'
- 去掉
修复后的完整代码:
import requests import csv from pprint import pprint as pp aHeader = ['name', 'birth_year', 'height', 'mass'] # 初始化CSV文件并写入表头 with open('star_wars_people2.csv', 'w', newline='') as file: writer = csv.DictWriter(file, fieldnames=aHeader) writer.writeheader() def get_info(character_data): # 从单个字典提取字段,构造符合表头的字典 row_data = { 'name': character_data['name'], 'birth_year': character_data['birth_year'], 'height': character_data['height'], 'mass': character_data['mass'] } # 追加写入一行数据 with open('star_wars_people2.csv', 'a', newline='') as aFile: writer = csv.DictWriter(aFile, fieldnames=aHeader) writer.writerow(row_data) for i in range(5): user_input = input("请输入1到83之间的数字,查询对应的星战角色:") endpoint2 = f'https://swapi.dev/api/people/{user_input}/' response = requests.get(endpoint2) data = response.json() pp(data) user_input2 = input("是否要将该信息写入文件?(y/n) ") if user_input2.lower() == 'y': get_info(data) else: print('没问题!')
- 列表API代码能运行的原因:请求
/api/people/返回的字典包含results键,data['results']是多个角色字典组成的列表,所以for item in data['results']可以遍历每个角色字典,自然能通过item['name']访问字段。
内容的提问来源于stack exchange,提问作者S-Gorton
相关产品推荐
相关产品推荐

