You need to enable JavaScript to run this app. while循环扩展列表时出现TypeError: string indices must be integers报错咨询
优惠活动
大模型
产品
解决方案
定价
更多

while循环扩展列表时出现TypeError: string indices must be integers报错咨询

报错根因定位
  • 传参完全不匹配:fun设计为接收带Name1列的DataFrame,但while循环里传入的是diff中的单个姓名字符串,给字符串做['Name1']的键索引,必然触发TypeError: string indices must be integers
  • fun本身存在低级错误:原代码return name2_list, score_list.append中,score_list.append是方法对象,不是实际的得分列表;且误用全局变量存结果,每次调用都会往全局列表重复堆数据,多次调用后数据完全混乱
  • 数据追加逻辑错误:直接把嵌套列表、整个集合append到Series中,相当于把整个嵌套结构当成单个单元格的内容存储,最终才会出现某一行Name2是长列表的嵌套结构
  • 循环逻辑存在硬伤:处理完当前批次的diff后,既没有把当前批次的姓名加入已处理集合,也没有重新计算新的待办名单,要么无限循环,要么反复爬取同一姓名浪费资源
分步骤修复操作

1. 重构爬取函数,适配单个姓名输入

彻底废弃原来按DataFrame入参设计的fun,改成直接接收单个姓名字符串作为参数,返回平级的(关联姓名, 得分)元组列表,去掉全局变量避免数据污染:

import requests
from bs4 import BeautifulSoup

def crawl_single_name(name: str):
    # 用占位符代替实际站点路径,避免外链
    url = f"目标站点路径/{name}"
    soup = BeautifulSoup(requests.get(url).content, "html.parser")

    # 提取关联姓名和得分
    neighbor_list = [a.text.strip() for a in soup.select("#card_mini_audience .site>a")]
    score_list = [float(s.text.strip()) for s in soup.select("#card_mini_audience .overlap>.truncation")]

    # 直接返回平级元组列表,比如[('Julie',31.9),('Mike',30.9)],无嵌套
    return list(zip(neighbor_list, score_list))

这一步修改完成后,传参不匹配的报错会直接消失。

2. 统一用DataFrame管理数据集

废弃零散的next_name2、name1列表,用DataFrame统一存储所有数据,从根源避免后续拆分、追加的麻烦:

import pandas as pd

# 原始数据集直接初始化
raw_data = [
    ("John", "Chris", 15.4),
    ("John", "Luke", 11.0),
    ("John", "Martin", 10.1),
    ("John", "Paul", 8.7),
    ("John", "Patty", 8.0),
    ("Patty", "Stephanie", 21.6),
    ("Patty", "Mila", 21.6),
    ("Patty", "Martin", 19.7),
    ("Patty", "Chris", 17.2),
    ("Patty", "Luke", 15.9),
    ("Meghan", "Kate", 5.0),
    ("Meghan", "Chris", 4.2),
    ("Meghan", "William", 4.1),
    ("Meghan", "John", 3.2),
    ("Meghan", "Stephen", 3.0)
]
df = pd.DataFrame(raw_data, columns=["Name1", "Name2", "Score"])

# 记录已经爬过数据的姓名(即已经作为Name1出现过的姓名)
processed_names = set(df["Name1"])

3. 重写while循环,实现平级追加和自动终止

核心逻辑为:每次处理当前待办名单里的所有姓名,把爬取到的所有关联关系拆成平级行追加,再更新待办名单,直到没有新的待处理姓名为止:

# 首次计算待办名单:所有在Name2里出现过、但还没作为Name1爬过数据的姓名
diff = set(df["Name2"]) - processed_names

while len(diff) > 0:
    new_rows = []
    # 遍历当前批次所有待处理姓名
    for name in diff:
        # 跳过已经处理过的姓名,避免重复爬取
        if name in processed_names:
            continue
        # 爬取当前姓名的所有关联关系
        pairs = crawl_single_name(name)
        # 把每个关联对转成标准行结构:[当前处理的姓名, 关联姓名, 得分]
        for neighbor, score in pairs:
            new_rows.append( (name, neighbor, score) )
    
    # 把新得到的平级行拼接到原数据集后面,不会出现嵌套单元格
    new_row_df = pd.DataFrame(new_rows, columns=["Name1", "Name2", "Score"])
    df = pd.concat([df, new_row_df], ignore_index=True)

    # 把当前批次处理完的姓名加入已处理集合
    processed_names.update(diff)

    # 重新计算待办名单:全量出现过的姓名里,还没爬过数据的
    all_occurred = set(df["Name1"]) | set(df["Name2"])
    diff = all_occurred - processed_names

原来的嵌套行问题就是因为直接把嵌套结构塞进单元格,修改后每一条数据都是单独的一行,Name1、Name2、Score都是单值,完全和原始数据集结构一致;同时循环会在所有姓名爬取完成后自动终止,不会无限运行。

内容的提问来源于stack exchange,提问作者V_sqrt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 20:45:06