You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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")

问题原因与解决方案

  1. 错误根源:请求单条人物数据(/api/people/{id}/)时,response.json()返回的是单个字典对象,而非包含多个字典的列表。但你在get_info函数里用for item in data循环,会把字典的键名(字符串类型)遍历出来(比如'name'、'birth_year'),再尝试用item['name']访问字符串的索引,自然触发"string indices must be integers"错误。

  2. 修复步骤:

    • 去掉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('没问题!')
  1. 列表API代码能运行的原因:请求/api/people/返回的字典包含results键,data['results']是多个角色字典组成的列表,所以for item in data['results']可以遍历每个角色字典,自然能通过item['name']访问字段。

内容的提问来源于stack exchange,提问作者S-Gorton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 10:53:13