网页数据爬取至Excel:拆分sectionaltimes与splittimes字段求助
解决嵌套字段
splittimes和sectionaltimes的展开问题 你的代码目前将嵌套的列表字段保留为原始列表/字符串形式,需要把它们拆分为单独的列并入DataFrame后再导出Excel。以下是修改后的实现方案:
修改后的完整代码
import requests import json import pandas as pd import xlsxwriter pd.set_option('display.max_rows', 500) pd.set_option('display.max_columns', 500) pd.set_option('display.width', 1000) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:103.0) Gecko/20100101 Firefox/103.0', 'Accept-Language': 'en-US,en;q=0.5' } def expand_list_column(df, col_name, prefix): """将列表类型的字段展开为带前缀的独立列""" expanded_df = df[col_name].apply(pd.Series) expanded_df.columns = [f"{prefix}_{idx}" for idx in expanded_df.columns] return df.drop(col_name, axis=1).join(expanded_df) df = pd.DataFrame() for race in range(1, 9): url = f"https://s3-ap-southeast-2.amazonaws.com/racevic.static/2015-01-01/flemington/sectionaltimes/race-{race}.json?callback=sectionaltimes_callback" r = requests.get(url, headers=headers) json_obj = json.loads(r.text.split('sectionaltimes_callback(')[1].rsplit(')', 1)[0]) # 用json_normalize处理嵌套字典,生成基础DataFrame main_df = pd.json_normalize(json_obj['Horses']) # 展开splittimes字段 if 'splittimes' in main_df.columns: main_df = expand_list_column(main_df, 'splittimes', 'split') # 展开sectionaltimes字段 if 'sectionaltimes' in main_df.columns: main_df = expand_list_column(main_df, 'sectionaltimes', 'section') df = pd.concat([df, main_df], ignore_index=True) # 导出Excel,不包含索引列 with pd.ExcelWriter("20150101.xlsx", engine='xlsxwriter') as writer: df.to_excel(writer, index=False)
关键修改说明
- 列表字段展开函数:
expand_list_column将每个列表类型的字段拆分为多个独立列,比如splittimes列表的第0个元素会生成split_0列,第1个元素生成split_1列,以此类推,避免字段以长字符串形式存储。 - 使用
pd.json_normalize:替代原生pd.DataFrame初始化数据,能自动展开Horse对象中的嵌套字典字段(如存在多层嵌套的属性)。 - 优化合并逻辑:
pd.concat添加ignore_index=True,避免多次合并后出现索引重复,无需额外调用reset_index。 - 规范Excel导出:用
ExcelWriter上下文管理器处理导出,同时设置index=False避免导出无用的索引列。
针对字典型列表的扩展方案
如果splittimes/sectionaltimes的列表元素是带键的字典(如包含distance、time等属性),可以改用以下函数展开,生成更清晰的列名(如split_0_distance、split_0_time):
def expand_list_of_dicts(df, col_name, prefix): expanded_dfs = [] for idx, row in df.iterrows(): item_df = pd.DataFrame(row[col_name]).add_prefix(f"{prefix}_{idx}_") expanded_dfs.append(item_df) expanded_df = pd.concat(expanded_dfs, axis=1) return df.drop(col_name, axis=1).join(expanded_df)
内容的提问来源于stack exchange,提问作者Learner
相关产品推荐
相关产品推荐

