Python三层for循环爬取数据写入CSV仅保留最后一次值问题咨询
问题根因
你的代码存在两个核心问题导致文件被覆盖:
- 每次循环都会用当前单次爬取的结果覆盖
all_dfs变量,没有累加存储历史爬取数据 - pandas的
to_csv方法默认mode='w'即覆盖写入模式,每次执行都会清空原有文件内容,仅写入当前循环的单批次数据
解决方案
方案1:先汇总所有数据再统一导出(推荐,性能更高)
适合爬取总数据量不会超出内存的场景,避免频繁磁盘IO操作,出错概率更低。
import pandas as pd # 循环开始前初始化空列表存储所有爬取到的df df_list = [] for ano in lista_ano: for distribuidora in lista_distribuidores: for mes in lista_mes: scraping = pd.read_html('https://www2.aneel.gov.br/aplicacoes/indicadores_de_qualidade/decFecSegMensal.cfm?mes={}&ano={}®iao=SE&distribuidora={}&tipo=d'.format(mes,ano,distribuidora)) dfs = pd.DataFrame(scraping[0]) dfs.drop(dfs.tail(3).index, inplace=True) dfs.drop(dfs.head(2).index, inplace=True) dfs = dfs.assign(MES = mes, ANO = ano, DISTRIBUIDORA = distribuidora) # 将当前处理好的df加入列表 df_list.append(dfs) # 所有循环结束后合并所有df,统一导出 all_dfs = pd.concat(df_list, ignore_index=True) all_dfs.to_csv('final_data.csv', encoding='utf-8', index=False)
方案2:循环内追加写入(适合数据量过大无法全部存入内存的场景)
每次爬取完成后直接追加到CSV文件末尾,自动控制表头写入逻辑,避免表头重复:
import pandas as pd import os # 先判断目标文件是否存在,用于控制是否写入表头 file_exists = os.path.exists('final_data.csv') for ano in lista_ano: for distribuidora in lista_distribuidores: for mes in lista_mes: scraping = pd.read_html('https://www2.aneel.gov.br/aplicacoes/indicadores_de_qualidade/decFecSegMensal.cfm?mes={}&ano={}®iao=SE&distribuidora={}&tipo=d'.format(mes,ano,distribuidora)) dfs = pd.DataFrame(scraping[0]) dfs.drop(dfs.tail(3).index, inplace=True) dfs.drop(dfs.head(2).index, inplace=True) dfs = dfs.assign(MES = mes, ANO = ano, DISTRIBUIDORA = distribuidora) # 追加写入,mode设为a,文件不存在就写表头,存在就跳过表头 dfs.to_csv('final_data.csv', encoding='utf-8', mode='a', header=not file_exists, index=False) # 第一次写入后修改标记,后续不再写表头 file_exists = True
注意事项
- 两种方案都加了
index=False参数,避免导出时把pandas的默认索引列存入CSV文件,不需要可自行删除 - 爬取公共站点建议加适当的延时,避免请求频率过高被站点封禁,可在循环内加
time.sleep(1)调整请求间隔
内容的提问来源于stack exchange,提问作者GLVieira
相关产品推荐
相关产品推荐

