Python用BeautifulSoup解析XML时如何解决列表索引越界错误?
问题:解析XML生成pandas DataFrame时出现IndexError错误
你需要解析以下XML文件生成pandas DataFrame:
<?xml version="1.0" encoding="UTF-8"?> <Entries> <EntrySynopsisDetail_1_0> <EntryID>262148</EntryID> <EntryTitle>Establishment of the Graduate Internship Program</EntryTitle> <CategoryOfEntry>ENG</CategoryOfEntry> </EntrySynopsisDetail_1_0> <EntrySynopsisDetail_1_0> <EntryID>2667654</EntryID> <EntryTitle>Call for Mobility Program</EntryTitle> <CategoryOfEntry>ENG</CategoryOfEntry> <CategoryOfEntry>MAT</CategoryOfEntry> </EntrySynopsisDetail_1_0> </Entries>
你的实现代码如下:
from bs4 import BeautifulSoup import pandas as pd fd = open("file_120123.xml",'r') data = fd.read() Bs_data = BeautifulSoup(data,'xml') ID = Bs_data.find_all('EntryID') Title = Bs_data.find_all('EntryTitle') try: Cat = Bs_data.find_all('CategoryOfEntry') except IndexError: Cat = '' CatDict = { "ENG":"English", "MAT" :"Mathematics" } dataDf = [] for i in range(0,len(ID)): if (Cat[i] == CatDict): Cat[i] == CatDict.get(Cat[i]) rows = [ID[i].get_text(), Title[i].get_text(), Cat[i]) dataDf.append(rows) df = pd.DataFrame(dataDf, columns =['ID', 'Title', 'Category'], dtype=float) df.to_csv('120123.csv')
运行代码时,在if (Cat[i] == CatDict):行的Cat[i]处出现IndexError: list index out of range错误,需要解决该问题。
问题分析与修复方案
错误根源
- 标签匹配逻辑错误:你把所有
<CategoryOfEntry>标签提取成一个全局列表,但每个条目(<EntrySynopsisDetail_1_0>)下的类别数量不同,直接按ID的索引去取Cat列表的元素,必然出现索引越界。 - 存在多个语法/逻辑错误:
try...except块无效:find_all不会抛出IndexError,无匹配标签时返回空列表,捕获逻辑完全没用。- 类别匹配逻辑错误:
Cat[i] == CatDict是把标签对象和字典直接比较,永远为False;且用双等号==代替赋值号=,根本不会修改值。 - 语法错误:
rows列表的括号不匹配;dtype=float会把ID转成浮点数,没必要且可能出错。
修复后的代码
from bs4 import BeautifulSoup import pandas as pd # 读取XML文件,用with语句自动管理资源 with open("file_120123.xml",'r') as fd: data = fd.read() Bs_data = BeautifulSoup(data,'xml') CatDict = {"ENG":"English", "MAT":"Mathematics"} dataDf = [] # 遍历每个条目节点,保证ID、Title、Category一一对应 for entry in Bs_data.find_all('EntrySynopsisDetail_1_0'): # 提取当前条目的ID和Title entry_id = entry.find('EntryID').get_text() entry_title = entry.find('EntryTitle').get_text() # 提取当前条目的所有类别,转换为字典对应的名称 categories = entry.find_all('CategoryOfEntry') # 处理无类别的情况,多类别用逗号分隔(也可存为列表) if categories: cat_names = [CatDict.get(cat.get_text(), cat.get_text()) for cat in categories] category = ', '.join(cat_names) else: category = '' dataDf.append([entry_id, entry_title, category]) # 生成DataFrame,自动推断类型,避免强制转float df = pd.DataFrame(dataDf, columns=['ID', 'Title', 'Category']) df.to_csv('120123.csv', index=False)
关键改进点
- 按条目节点遍历:直接遍历每个
<EntrySynopsisDetail_1_0>,确保每个条目的子标签是对应的,彻底解决索引越界问题。 - 类别处理优化:对每个条目单独提取类别,自动转换为字典中的名称,同时处理无类别的情况。
- 语法修正:修复括号不匹配、赋值符号错误等问题;用
with语句管理文件,避免资源泄漏。 - 类型优化:去掉
dtype=float,让pandas自动推断数据类型,更合理。
内容的提问来源于stack exchange,提问作者tachyon
相关产品推荐
相关产品推荐

