前言在爬虫工程化开发流程中纯文本文件仅能满足简易数据归档需求当采集数据具备多字段结构化特征、需要后续进行筛选、排序、统计、表格查看等操作时文本格式的局限性便会凸显。CSV 作为通用的逗号分隔值文件格式凭借轻量、跨软件兼容、解析高效、无需额外部署服务等特性成为中小规模爬虫项目首选的结构化数据持久化方案。CSV 文件可直接使用 Office Excel、WPS、记事本、各类代码编辑器打开查看与编辑同时主流编程语言、数据分析工具均提供成熟的读写接口能够无缝对接数据清洗、可视化、二次分析等后续流程。相较于传统 TXT 文本CSV 天然支持行列结构划分完美适配爬虫场景中列表嵌套字典的标准化数据格式可清晰区分标题、时间、链接、内容等不同字段。本文基于 Python 内置csv标准库与第三方高性能拓展库结合前文分页爬虫、数据采集案例系统讲解 CSV 文件的创建、单行 / 多行写入、表头定义、数据追加、文件读取、编码兼容、大文件处理、异常防护等全流程实战内容同时拆解底层运行原理、不同写法的优劣对比以及爬虫场景下的落地规范帮助开发者掌握工业级 CSV 数据持久化技术。本文开发运行依赖库及官方地址如下csvPython 内置 CSV 读写标准库Python 标准库无需额外安装os内置路径处理库Python 标准库无需额外安装time内置时间工具库Python 标准库无需额外安装requests网络请求库https://pypi.org/project/requests/bs4BeautifulSoup网页解析库https://pypi.org/project/beautifulsoup4/lxmlHTML 解析引擎https://pypi.org/project/lxml/一、CSV 文件基础认知1.1 CSV 格式规范与特性CSV 全称 Comma-Separated Values即逗号分隔值文件其本质是一种纯文本格式文件使用英文逗号作为字段分隔符换行符作为行分隔符。每一行代表一条完整数据每一个被逗号分割的片段对应一个独立字段。标准 CSV 文件分为表头行与数据行两大结构表头行位于文件首行用于定义每一列的字段名称例如标题、发布时间、作者、链接数据行紧随表头之后按列顺序填充对应数据。该结构与数据库表、Excel 表格逻辑完全一致也是其具备高兼容性的核心原因。从爬虫应用角度总结 CSV 核心特性文件体积小、读写速度快、占用系统资源低支持跨平台、跨软件打开编辑原生支持结构化行列数据适配爬虫主流数据结构纯文本存储不存在格式错乱问题。其短板为不支持复杂单元格格式、大数据量下查询效率弱于专业数据库适合十万条以内中小规模数据存储。1.2 Python csv 库核心组件说明Python 内置csv库是操作 CSV 文件的原生工具无需 pip 安装库中封装了多个核心类与方法适配不同读写场景结合爬虫使用频率核心组件分类说明如下表表格核心组件功能作用适用场景writer基础写入器按行写入列表类型数据单行、批量多行简单数据写入DictWriter字典写入器按字段映射写入字典数据爬虫字典格式结构化数据写入主流reader基础读取器按行读取数据并转为列表读取简单无表头 CSV 文件DictReader字典读取器结合表头将数据转为字典读取带表头的标准结构化 CSV 文件主流在爬虫项目中采集后的数据大多以字典、列表嵌套字典形式存在因此DictWriter 与 DictReader是使用频率最高的两个组件也是本文重点讲解内容。1.3 编码与换行符适配规则中文乱码是 CSV 操作的高频问题不同软件对 CSV 默认编码存在差异。Windows 系统下 Excel 打开 UTF-8 编码 CSV 文件易出现乱码而记事本、代码编辑器、Linux/macOS 系统默认兼容 UTF-8。行业通用解决方案为创建文件时指定encodingutf-8-sig该编码格式会在文件头部添加 BOM 标记完美兼容 Windows 平台 Excel 软件同时不影响其他编辑器正常读取。换行符方面csv库内部已封装换行处理逻辑代码中无需手动添加\n可直接规避不同系统换行符不统一导致的格式错乱问题。二、基础写入实战创建 CSV 与表头设置2.1 writer 基础写入列表数据2.1.1 场景分析csv.writer适用于数据为一维列表、二维列表的简单场景不依赖字段名映射按照列表元素顺序依次写入单元格。该写法逻辑简单适合无固定表头、临时数据存储场景。结合with上下文管理器实现文件自动关闭保证资源安全释放。2.1.2 单行数据写入代码实现python运行import csv # 定义文件存储路径 csv_path ./simple_data.csv # 单行列表数据对应一行多列内容 single_row [Python爬虫, CSV持久化, 2026-06-11, 技术教程] # 打开文件并创建写入器 with open(csv_path, modew, encodingutf-8-sig, newline) as f: # 初始化csv写入对象 writer csv.writer(f) # 写入单行数据 writer.writerow(single_row) print(单行列表数据写入完成)2.1.3 代码原理解析newline 参数作用文件打开参数中newline是 CSV 操作的标准配置。Python 在 Windows 系统下默认会自动补充换行符若不设置该参数写入后 CSV 文件会出现空行破坏表格结构。该参数可屏蔽系统自动换行逻辑保证文件格式整洁。writerow () 方法原理writerow()接收一维列表作为参数会自动将列表内元素用英文逗号分隔拼接为标准 CSV 行文本并写入文件开发者无需手动处理分隔符降低格式出错概率。编码规则encodingutf-8-sig为爬虫 CSV 存储通用编码兼顾中文显示与 Excel 兼容性是项目开发中的强制规范。2.1.4 多行数据写入代码实现当存在多条数据时使用writerows()方法可一次性写入二维列表相较于循环调用writerow()执行效率更高适合批量数据落地。python运行import csv csv_path ./multi_simple_data.csv # 二维列表外层代表行内层代表列 multi_rows [ [分页抓取, 文本存储, CSV存储], [Excel写入, 延时设置, 异常重试], [爬虫实战, 数据采集, 持久化] ] with open(csv_path, modew, encodingutf-8-sig, newline) as f: writer csv.writer(f) # 批量写入多行数据 writer.writerows(multi_rows) print(多行列表数据批量写入完成)2.1.5 原理解析writerows()接收二维列表参数遍历外层每一个一维列表逐行完成写入。该方法属于批量操作接口IO 交互次数更少在数据量较大时性能优于循环单行写入。2.2 DictWriter 字典写入带表头爬虫主流用法2.2.1 场景分析爬虫解析后的结构化数据基本为字典格式每条数据的键对应字段名称值对应字段内容。csv.DictWriter专门适配字典数据支持自定义表头可实现字段与数据精准映射是正式爬虫项目的标准写法。该组件会根据表头顺序自动提取字典中对应键的值写入单元格无需人工排序字段。2.2.2 单条字典数据写入python运行import csv csv_path ./news_data.csv # 定义表头列表决定CSV列名与列顺序 field_names [标题, 发布时间, 作者, 内容摘要] # 单条字典数据键必须与表头名称一一对应 news_dict { 标题: CSV文件数据持久化教程, 发布时间: 2026-06-11, 作者: 爬虫工程师, 内容摘要: 讲解Python爬虫CSV全流程存储技巧 } with open(csv_path, modew, encodingutf-8-sig, newline) as f: # 初始化字典写入器绑定文件与表头 dict_writer csv.DictWriter(f, fieldnamesfield_names) # 写入表头仅执行一次 dict_writer.writeheader() # 写入单条字典数据 dict_writer.writerow(news_dict) print(带表头的字典数据写入完成)2.2.3 代码原理解析fieldnames 参数原理fieldnames用于定义 CSV 文件的表头同时规定数据列的排列顺序。字典写入器会以此列表为依据按顺序读取字典内对应键的值实现字段映射。若字典缺少表头中的键对应单元格会留空保证文件结构不被破坏。writeheader () 方法原理该方法专门用于写入表头行仅在文件首次创建时调用一次。重复调用会导致表头多次写入破坏数据结构这是开发中需要重点规避的问题。字典映射逻辑writerow()接收字典参数内部会遍历表头列表依次提取字典中对应键的 value转换为标准 CSV 行数据写入文件全程自动完成字段匹配大幅降低结构化数据的格式处理成本。三、进阶实战分页爬虫结合 CSV 批量存储3.1 场景说明结合第一篇分页抓取案例实现分页采集 批量写入 CSV完整链路。逐页抓取网页数据解析为字典格式分批存入同一个 CSV 文件同时区分首次创建文件写入表头与后续追加数据不重复写入表头模拟真实线上爬虫运行逻辑。3.2 完整代码实现python运行import csv import requests from bs4 import BeautifulSoup # 全局请求配置 HEADERS { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36 } # 爬虫与存储配置 BASE_URL https://demo-static-page.com/list/ CSV_SAVE_PATH ./page_crawl_data.csv # 定义CSV表头 FIELD_NAMES [新闻标题, 发布时间, 内容摘要, 所属页码] # 分页范围 START_PAGE 1 END_PAGE 5 def parse_page_data(page_num): 解析单页数据返回字典列表 url f{BASE_URL}{page_num}.html response requests.get(url, headersHEADERS, timeout10) response.encoding utf-8 soup BeautifulSoup(response.text, lxml) item_list soup.find_all(div, class_news-item) data_list [] for item in item_list: news_title item.find(h3, class_news-title).get_text(stripTrue) publish_time item.find(span, class_publish-time).get_text(stripTrue) summary item.find(p, class_summary).get_text(stripTrue) # 封装为字典 data_dict { 新闻标题: news_title, 发布时间: publish_time, 内容摘要: summary, 所属页码: page_num } data_list.append(data_dict) return data_list if __name__ __main__: # 标记文件是否为新文件用于判断是否写入表头 is_new_file True for page in range(START_PAGE, END_PAGE 1): print(f正在采集并存储第 {page} 页数据) page_data parse_page_data(page) # 追加模式打开文件 with open(CSV_SAVE_PATH, modea, encodingutf-8-sig, newline) as f: dict_writer csv.DictWriter(f, fieldnamesFIELD_NAMES) # 新文件写入表头后续页面不再重复写入 if is_new_file: dict_writer.writeheader() is_new_file False # 批量写入当前页所有数据 dict_writer.writerows(page_data) print(所有分页数据已全部存入CSV文件)3.3 代码原理解析文件模式选择逻辑代码中统一使用modea追加模式打开文件适配分页分批写入场景。爬虫逐页循环执行每一页采集完成后向文件末尾追加数据不会清空历史内容支持断点续爬。表头防重复机制定义布尔变量is_new_file作为标记仅在第一次打开文件时执行writeheader()写入表头。标记置为 False 后后续所有分页不再写入表头从根源上解决表头重复、文件结构错乱问题这是分页爬虫 CSV 存储的核心设计思路。writerows () 批量写入优化单页解析得到的是字典列表直接使用writerows()批量写入相较于循环writerow()减少文件 IO 次数提升运行效率。IO 操作是程序性能瓶颈批量写入是爬虫优化的基础手段。数据结构联动原理解析函数输出的字典键名与全局表头FIELD_NAMES严格保持一致保证字段精准匹配。若键名与表头不对应会出现数据错位、空单元格等问题这是结构化数据存储的基础规范。四、CSV 数据读取实战4.1 reader 基础读取读取为列表适用于无表头或不需要区分字段的场景读取后每一行数据转换为一维列表。python运行import csv csv_path ./multi_simple_data.csv with open(csv_path, moder, encodingutf-8-sig) as f: reader csv.reader(f) # 遍历每一行数据 for row in reader: print(f行数据{row})原理解析csv.reader逐行读取文件内容自动按逗号分割字段返回列表格式数据。读取过程中会自动忽略 CSV 格式控制字符仅保留有效业务数据。4.2 DictReader 字典读取带表头主流用法针对带标准表头的 CSV 文件DictReader会自动将首行作为字典的键每行数据作为对应的值读取结果为字典格式字段语义清晰便于二次数据处理。python运行import csv csv_path ./page_crawl_data.csv with open(csv_path, moder, encodingutf-8-sig) as f: # 初始化字典读取器自动识别表头 dict_reader csv.DictReader(f) # 遍历所有数据行 for index, row in enumerate(dict_reader, 1): print(f第{index}条数据) print(f标题{row[新闻标题]}发布时间{row[发布时间]})原理解析DictReader无需手动指定表头会自动读取文件第一行作为字段名。遍历得到的每一条数据都是字典可通过键名精准提取指定字段适合数据筛选、清洗、二次加工等后续操作。五、复杂场景处理与异常防护5.1 字段包含逗号 / 换行符的兼容处理部分采集内容简介、正文中会自带英文逗号、换行符手动拼接文本会破坏 CSV 分隔规则。csv库内部已做转义处理使用官方写入方法可自动识别特殊字符并添加引号包裹无需开发者额外处理。测试案例python运行import csv csv_path ./special_char_data.csv field_names [内容, 备注] # 数据包含逗号与换行符 test_data { 内容: 爬虫,CSV存储\n基础教程, 备注: 包含特殊符号测试 } with open(csv_path, modew, encodingutf-8-sig, newline) as f: writer csv.DictWriter(f, fieldnamesfield_names) writer.writeheader() writer.writerow(test_data) print(特殊字符数据写入完成)运行后打开 CSV 文件可看到特殊字符被自动包裹表格结构保持完整验证了库内置转义能力的可靠性。5.2 自动创建文件与文件夹结合os库实现路径自动化处理若目标文件夹不存在则自动创建避免路径报错提升爬虫自动化程度。python运行import csv import os # 定义多级路径 folder_path ./crawl_csv/20260611 file_name daily_data.csv full_path os.path.join(folder_path, file_name) field_names [标题, 时间] test_data [{标题: 测试数据, 时间: 2026-06-11}] # 检测并创建文件夹 if not os.path.exists(folder_path): os.makedirs(folder_path) with open(full_path, modew, encodingutf-8-sig, newline) as f: writer csv.DictWriter(f, fieldnamesfield_names) writer.writeheader() writer.writerows(test_data) print(多级目录CSV文件创建写入完成)5.3 异常捕获与容错处理网络异常、文件权限不足、磁盘空间已满等问题都会导致 CSV 读写失败在核心逻辑外层增加try...except异常捕获保证程序稳定运行。python运行import csv import requests from bs4 import BeautifulSoup HEADERS {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36} CSV_PATH ./error_protect.csv FIELD_NAMES [标题, 时间] try: # 采集数据 res requests.get(https://demo-static-page.com/list/1.html, headersHEADERS, timeout10) res.encoding utf-8 soup BeautifulSoup(res.text, lxml) title soup.find(h1).get_text(stripTrue) data [{标题: title, 时间: 2026-06-11}] # 写入CSV with open(CSV_PATH, modea, encodingutf-8-sig, newline) as f: writer csv.DictWriter(f, fieldnamesFIELD_NAMES) writer.writerows(data) print(数据写入成功) except FileNotFoundError: print(文件路径错误目录不存在) except PermissionError: print(文件权限不足无法写入) except Exception as e: print(f程序运行异常{str(e)})六、CSV 存储性能优化方案6.1 减少文件打开关闭次数分页爬虫循环中若每一页都重复打开、关闭文件会产生大量 IO 开销。优化方案为将文件打开操作移至循环外部全程保持文件打开状态循环内持续写入所有分页采集完成后自动关闭文件。优化示例python运行import csv csv_path ./optimize_csv.csv field_names [字段1, 字段2] data_list [{字段1: f数据{i}, 字段2: f内容{i}} for i in range(100)] # 单次打开文件循环内持续写入 with open(csv_path, modew, encodingutf-8-sig, newline) as f: writer csv.DictWriter(f, fieldnamesfield_names) writer.writeheader() for data in data_list: writer.writerow(data) print(优化后写入完成)6.2 批量缓存写入数据量极大时可设置缓存列表采集多条数据后统一批量写入进一步降低 IO 交互频率提升整体运行速度。该方案适用于高并发、海量数据采集场景。