循环生成字典键动态变化,Python爬虫如何正确将数据写入CSV文件
问题原因
你目前的代码运行出错的核心原因是:
csv.DictWriter初始化时指定的fieldnames必须和CSV文件已有的表头完全一致,你每次都传入当前页数据的键,和原有表头不匹配时就会抛出异常- CSV本身是固定表头的结构化格式,创建后无法直接追加新列,新增列需要重写整个文件保证所有行的字段对齐
解决方案
根据你的爬取场景可以选择两种不同的处理方案:
方案1:先全量采集字段再写入(推荐,性能更高)
如果可以提前遍历所有页面、收集到所有可能出现的表头字段,再统一写入数据是最稳妥的方案,不会有频繁读写文件的性能损耗。
示例代码:
import csv import os from bs4 import BeautifulSoup # 第一步:遍历所有页面收集全量表头 all_fields = set() # 替换为你遍历所有页面的逻辑 for page in all_site_pages: trs = BeautifulSoup(page.content, 'lxml').find_all('tr') for tr in trs: field_name = tr.find_all('td')[0].text.strip() all_fields.add(field_name) # 可手动排序all_fields保证表头顺序符合预期 all_fields = list(all_fields) # 第二步:统一提取数据写入CSV with open('file.csv', 'w', newline='', encoding='utf-8') as f: # restval参数指定缺失字段填充空值,extrasaction参数忽略多余字段避免报错 wr = csv.DictWriter(f, fieldnames=all_fields, restval='', extrasaction='ignore') wr.writeheader() for page in all_site_pages: trs = BeautifulSoup(page.content, 'lxml').find_all('tr') data = {} for tr in trs: tds = tr.find_all('td') data[tds[0].text.strip()] = tds[1].text.strip() wr.writerow(data)
方案2:动态扩展表头(适合增量爬取场景)
如果是增量爬取、无法提前遍历所有页面,可以每次写入前读取已有表头,合并新字段后重写整个CSV。
示例代码:
import csv import os def append_to_csv(new_data): file_path = 'file.csv' # 文件不存在直接创建写入 if not os.path.exists(file_path): with open(file_path, 'w', newline='', encoding='utf-8') as f: wr = csv.DictWriter(f, fieldnames=new_data.keys(), restval='', extrasaction='ignore') wr.writeheader() wr.writerow(new_data) return # 文件已存在,读取旧表头和旧数据 with open(file_path, 'r', encoding='utf-8') as f: reader = csv.DictReader(f) old_fields = reader.fieldnames old_rows = list(reader) # 合并表头,新字段默认追加到表头末尾 new_fields = old_fields.copy() for key in new_data.keys(): if key not in new_fields: new_fields.append(key) # 重写整个CSV,旧行自动填充新增字段的空值 with open(file_path, 'w', newline='', encoding='utf-8') as f: wr = csv.DictWriter(f, fieldnames=new_fields, restval='', extrasaction='ignore') wr.writeheader() wr.writerows(old_rows) wr.writerow(new_data)
注意:该方案每次写入都需要读写全量CSV,数据量大时性能会明显下降,仅适合小数据量的增量爬取场景
内容的提问来源于stack exchange,提问作者Username
相关产品推荐
相关产品推荐

