如何解决pandas循环写入csv时数据被覆盖问题
问题原因
代码存在两个逻辑问题导致数据被覆盖:
- 存储单页数据的
temp列表定义在分页循环内部,每次翻页都会被重置为空列表,无法累计多页数据 - 每次分页爬取完成后直接调用
df.to_csv('samp.csv'),该方法默认写入模式为覆盖写(w),每执行一次就会清空文件原有内容写入当前页数据,循环结束后文件自然只保留最后一页的内容。之前尝试a追加模式未生效,是因为没有将模式参数传入to_csv方法,仅手动修改文件打开模式不会作用于pandas的默认写入逻辑。
目标爬取页面:AEAF协会成员列表
修复方案
优先选择全量爬取后一次性写入的实现,逻辑简单不易出错:
- 将汇总所有数据的列表移到分页循环外,每爬完一条数据就追加到全局列表中
- 所有分页爬取完成后,再将全量数据转为DataFrame一次性导出CSV
- 补充
index=False参数,避免pandas默认导出多余的行号列 - 修正请求URL中的HTML转义字符
&为实际请求需要的&
修正后可直接运行的代码:
import requests from bs4 import BeautifulSoup import pandas as pd headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36' } # 全局列表存储所有分页爬取的数据 all_data = [] for page in range(1, 3): r = requests.get( f'https://www.aeafa.es/asociados.php?provinput=&_pagi_pg={page}', headers=headers ) soup = BeautifulSoup(r.content, 'lxml') tag = soup.find_all('div', class_='col-md-8 col-sm-8') for pro in tag: data = [tup.text for tup in pro.find_all('p')] # 直接切片取值,减少冗余中间变量 Dirección = data[2][12:] Población = data[3][14:] Provincia = data[4][14:] Teléfono = "+" + data[5][11:].replace('.', "") Email = data[6][10:] all_data.append([Dirección, Provincia, Población, Teléfono, Email]) # 全量数据爬取完成后一次性写入CSV df = pd.DataFrame( all_data, columns=["Dirección", "Provincia", "Población", "Teléfono", "Email"] ) df.to_csv('samp.csv', index=False)
如果需要边爬边写(比如数据量极大不想全量存在内存里),可以调整写入逻辑:第一页写入时保留表头,后续页设置追加模式且关闭表头写入,示例写法:
# 第一页写入用覆盖模式 df.to_csv('samp.csv', index=False, mode='w') # 第二页及之后写入用追加模式,不写表头 df.to_csv('samp.csv', index=False, mode='a', header=False)
内容的提问来源于stack exchange,提问作者Amen Aziz
相关产品推荐
相关产品推荐

