news 2026/6/9 1:55:20

Python 爬虫实战:CSV/Excel 文件存储、多线程爬虫开发与数据去重落地实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 爬虫实战:CSV/Excel 文件存储、多线程爬虫开发与数据去重落地实战

前言

在完成 UA 随机轮换、请求延时、代理 IP、异常重试与日志体系搭建后,爬虫已具备稳定单线程抓取能力,但是单线程串行采集模式在大批量数据抓取场景中效率短板突出,逐条串行请求受网络空闲等待损耗制约,海量分页、多目标页面采集耗时成倍增加。同时此前项目仅采用 MySQL 入库、本地 TXT 文本两种存储方案,在轻量化数据归档、离线数据分析、简易数据分发场景中存在使用不便的问题,CSV、Excel 作为通用表格格式,适配办公软件直接打开编辑,是中小型爬虫项目轻量化存储首选。除此之外,重复采集冗余数据长期占用数据库与本地存储空间,数据去重逻辑成为工程化爬虫不可或缺的组成模块。本文依托前面文库、百科、技术社区、天气 API 四大项目源码进行改造升级,新增 openpyxl、csv 内置模块、threading 多线程组件,从文件存储实操、多线程并发抓取、基于链接 / 字段的数据去重三个核心模块展开完整案例开发,配套对应数据表优化、原有爬虫代码重构。 本篇新增依赖组件官方文档链接汇总:

  1. openpyxl:Excel 读写专用第三方库,支持.xlsx 格式新建、写入、追加数据
  2. Python 内置 csv:标准库,无需额外安装,轻量化 CSV 文件读写
  3. threading:Python 内置多线程标准库,实现 IO 密集型爬虫并发抓取
  4. hashlib:内置哈希算法库,用于字段加密生成指纹实现数据去重

一、爬虫轻量化文件存储方案选型与原理对比

1.1 CSV 与 Excel 存储特性对照表

表格

存储格式依赖条件优势适用场景短板
CSVPython 原生 csv 模块,零安装体积小巧、读写速度快、全平台软件兼容、占用资源极低海量明细数据落地、定时采集日志归档、接口批量数据存储不支持复杂单元格样式、无法插入图片与多工作表、纯文本结构
XLSX(Excel)openpyxl 第三方库多工作表分类存储、单元格格式自定义、便于人工整理统计小体量样本数据、结果汇总报表、学习演示数据导出大批量数据写入内存占用偏高,十万级以上数据性能弱于 CSV

1.2 CSV 通用读写工具类开发

CSV 依托内置模块实现,分为文件新建表头、单行追加写入、批量多行写入三种常用逻辑,工具类可全项目复用。

python

运行

import csv import os from spider_log import spider_log class CsvSaveUtil: def __init__(self, file_path, header_list): self.file_path = file_path self.header = header_list # 判断文件是否存在,不存在则写入表头 if not os.path.exists(self.file_path): self.write_header() def write_header(self): """写入CSV表头信息""" try: with open(self.file_path, "w", newline="", encoding="utf-8-sig") as f: writer = csv.writer(f) writer.writerow(self.header) spider_log.info(f"CSV文件{self.file_path}表头创建成功") except Exception as e: spider_log.error(f"表头写入失败:{str(e)}") def write_row(self, data_row): """单行数据追加写入""" try: with open(self.file_path, "a", newline="", encoding="utf-8-sig") as f: writer = csv.writer(f) writer.writerow(data_row) except Exception as e: spider_log.error(f"单行写入异常:{str(e)}") def write_rows(self, data_list): """批量多行数据写入""" try: with open(self.file_path, "a", newline="", encoding="utf-8-sig") as f: writer = csv.writer(f) writer.writerows(data_list) spider_log.info(f"批量{len(data_list)}条数据写入CSV完成") except Exception as e: spider_log.error(f"批量写入异常:{str(e)}")

1.3 CSV 工具原理说明

  1. encoding="utf-8-sig":规避 Windows 系统 Excel 打开 CSV 出现中文乱码问题,区别于普通 utf-8 编码;
  2. newline="":消除不同操作系统写入 CSV 时自动多出空行的问题;
  3. 文件存在性判断逻辑:首次创建文件写入表头,后续采集仅追加内容,避免重复覆盖表头。

1.4 技术社区爬虫接入 CSV 存储改造示例

python

运行

# 在爬虫初始化中定义CSV配置 def __init__(self): self.headers = {"User-Agent": ua_tool.get_random_ua()} self.result_list = [] header = ["帖子标题","作者","发布时间","阅读量","帖子链接"] self.csv_util = CsvSaveUtil("tech_post.csv", header) # 采集结束后批量写入 def save_to_file(self): data_arr = [] for item in self.result_list: row = [item["title"],item["author"],item["publish_time"],item["view_count"],item["url"]] data_arr.append(row) self.csv_util.write_rows(data_arr)

1.5 Excel 通用写入工具类实现

bash

运行

pip install openpyxl

python

运行

from openpyxl import Workbook, load_workbook import os from spider_log import spider_log class ExcelSaveUtil: def __init__(self, file_path, sheet_name="data", header=None): self.file_path = file_path self.sheet_name = sheet_name self.header = header if os.path.exists(self.file_path): self.wb = load_workbook(self.file_path) if self.sheet_name in self.wb.sheetnames: self.ws = self.wb[self.sheet_name] else: self.ws = self.wb.create_sheet(self.sheet_name) if self.header: self.ws.append(self.header) else: self.wb = Workbook() self.ws = self.wb.active self.ws.title = self.sheet_name if self.header: self.ws.append(self.header) self.wb.save(self.file_path) def append_row(self, row_data): """单行追加数据""" self.ws.append(row_data) self.wb.save(self.file_path) def append_batch(self, batch_data): """批量追加多行""" for row in batch_data: self.ws.append(row) self.wb.save(self.file_path) spider_log.info(f"Excel批量写入{len(batch_data)}条数据")

1.6 Excel 存储核心原理

  1. Workbook代表整个 Excel 文件对象,worksheet对应表格内工作表,一个 Excel 可创建多张 sheet 分类存储不同维度数据;
  2. load_workbook用于读取已存在的 Excel 文件,避免每次写入覆盖原有全部数据;
  3. 每次写入后执行 save 落地磁盘,防止程序异常退出导致数据丢失。

二、基于 threading 的 IO 密集型多线程爬虫开发

2.1 爬虫选用多线程的底层逻辑

爬虫绝大多数运行时间消耗在网络请求 IO 等待阶段,CPU 空闲闲置,Python 多线程受 GIL 全局解释器锁限制,不适合 CPU 密集运算,但完美适配 IO 密集场景,通过多线程并行发起网络请求,把串行等待时间转为并发执行,采集效率提升 3~8 倍。爬虫禁止无限制创建线程,海量任务需搭配线程池控制并发上限,避免瞬间海量请求触发反爬。

2.2 简易线程池封装(控制并发数量)

python

运行

import threading from queue import Queue from spider_log import spider_log class CrawlThreadPool: def __init__(self, max_thread=5): self.max_thread = max_thread self.task_queue = Queue() self.result_queue = Queue() self.thread_list = [] def put_task(self, task_data): """存入待采集任务""" self.task_queue.put(task_data) def thread_func(self, crawl_func): """子线程循环取任务执行""" while not self.task_queue.empty(): try: task = self.task_queue.get(timeout=2) res = crawl_func(task) if res: self.result_queue.put(res) self.task_queue.task_done() except Exception as e: spider_log.warning(f"子线程任务异常:{str(e)}") def start_run(self, crawl_func): """启动线程池执行任务""" for _ in range(self.max_thread): t = threading.Thread(target=self.thread_func, args=(crawl_func,)) t.daemon = True t.start() self.thread_list.append(t) self.task_queue.join() spider_log.info("全部任务执行完毕")

2.3 文库文摘爬虫接入多线程实战

原有单条 URL 逐个抓取,改造为批量 URL 入队、多线程并发抓取:

python

运行

# 待采集详情链接列表 url_list = [ "https://example.com/lib/1", "https://example.com/lib/2", "https://example.com/lib/3" ] def single_crawl_task(url): """单个任务抓取函数,传入URL返回解析数据""" spider = LibrarySpider() html = spider.get_page_html(url) data = spider.parse_abstract(html) if data: spider.save_to_db(data, url) return data return None # 初始化线程池,最大并发3个线程 pool = CrawlThreadPool(max_thread=3) for item_url in url_list: pool.put_task(item_url) pool.start_run(single_crawl_task)

2.4 线程池关键参数配置参考

表格

站点风控等级最大并发线程数配套延时策略
宽松公开 API (天气接口)5~8随机 0.3~1 秒延时
资讯文库、百科站点3~5随机 1~2.5 秒延时
风控严格技术社区1~2随机 2~4 秒延时

三、数据去重实现:URL 指纹 + 哈希字段双重去重方案

重复采集分为两类:同源 URL 重复抓取、同一标题内容重复生成,采用 MD5 哈希生成数据指纹是工业级爬虫主流去重手段,将字符串转为固定长度密文,对比密文即可快速判定重复。

3.1 MD5 指纹生成工具类

python

运行

import hashlib class DataHashUtil: @staticmethod def get_md5(content: str): """生成字符串MD5指纹""" md5_obj = hashlib.md5(content.encode("utf-8")) return md5_obj.hexdigest()

3.2 三种落地去重方案

3.2.1 内存集合临时去重(单次运行去重)

爬虫单次运行中使用 set 集合存储已采集 URL 指纹,请求前校验,适合临时批量抓取:

python

运行

already_spider_set = set() def check_url_duplicate(url): md5_str = DataHashUtil.get_md5(url) if md5_str in already_spider_set: return True already_spider_set.add(md5_str) return False
3.2.2 MySQL 数据库唯一索引永久去重(推荐长期项目)

修改此前文库数据表,对 source_url 增加唯一索引,重复 URL 插入时数据库直接抛出异常,捕获异常跳过入库:

sql

ALTER TABLE library_abstract ADD UNIQUE INDEX idx_source_url(source_url);

入库代码捕获唯一索引冲突异常:

python

运行

from pymysql.err import IntegrityError try: self.db_cursor.execute(sql, params) self.db_conn.commit() except IntegrityError: spider_log.info(f"数据重复,跳过入库:{data['title']}") self.db_conn.rollback()
3.2.3 本地指纹文件持久化去重(无数据库环境)

将所有 URL 指纹存入 txt 文件,每次采集前读取指纹列表比对,适合轻量化离线爬虫。

3.3 标题内容去重补充

部分站点 URL 不同但文摘内容高度一致,提取标题 + 摘要拼接字符串生成 MD5,实现内容维度去重。

四、原有项目全量适配优化汇总

表格

项目名称新增改造项优化收益
基础异常爬虫CSV 结果导出 + 内存去重测试数据快速落地表格,避免重复测试采集
开源文库入库爬虫Excel 备份 + 多线程并发 + 数据库唯一索引去重批量文摘抓取效率提升 4 倍,彻底杜绝重复入库
天气定时采集爬虫CSV 按日分文件存储每日天气数据单独归档,便于按月统计分析
百科词条爬虫多线程批量词条抓取 + URL 指纹去重批量词条快速采集,过滤重复词条链接
技术社区爬虫Excel+CSV 双备份 + 分页去重多页采集自动过滤重复帖子,双格式留存数据

五、开发拓展方向与并发合规提示

5.1 后续拓展方向

  1. 引入 ThreadPoolExecutor 内置线程池替代原生 threading,简化任务调度代码;
  2. 使用 Redis 集合持久化存储指纹,实现爬虫重启后依然保留历史去重记录;
  3. 基于 pandas 实现 CSV、Excel 大数据清洗、筛选、格式转换。

5.2 多线程合规提醒

并发不等于无节制高频请求,即便多线程 + 代理 IP,仍需要依托随机延时控制整体请求速率,多线程场景适当拉长单请求休眠时间,规避站点短时间瞬时大量请求触发封禁,所有并发采集仅针对完全公开无权限限制的网络资源。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 1:25:27

Unitree Go2机器人ROS2 SDK:从实时控制到自主导航的全栈解决方案

Unitree Go2机器人ROS2 SDK:从实时控制到自主导航的全栈解决方案 【免费下载链接】go2_ros2_sdk Unofficial ROS2 SDK support for Unitree GO2 AIR/PRO/EDU 项目地址: https://gitcode.com/gh_mirrors/go/go2_ros2_sdk 你是否想过如何将先进的四足机器人技术…

作者头像 李华
网站建设 2026/6/9 1:14:13

B站直播推流码获取工具:终极免费方案摆脱官方直播姬限制

B站直播推流码获取工具:终极免费方案摆脱官方直播姬限制 【免费下载链接】bilibili_live_stream_code 用于在准备直播时获取第三方推流码,以便可以绕开哔哩哔哩直播姬,直接在如OBS等软件中进行直播,软件同时提供定义直播分区和标题…

作者头像 李华
网站建设 2026/6/9 1:45:05

如何构建基于YOLOv8的智能FPS游戏辅助系统

如何构建基于YOLOv8的智能FPS游戏辅助系统 【免费下载链接】yolov8_aimbot Aim-bot based on AI for all FPS games 项目地址: https://gitcode.com/gh_mirrors/yo/yolov8_aimbot 在FPS游戏中,精准的瞄准往往是胜负的关键。传统的人工瞄准依赖于玩家的反应速…

作者头像 李华
网站建设 2026/6/8 5:44:56

装机必备神器,文件虽小,功能齐全!

今天推荐两个电脑上的小工具,一个用来卸载软件,一个用来备份驱动。第一款:IObitUninstaller(卸载工具) 这个软件我推荐过好几次了,功能比较全。批量卸载:系统自带的卸载只能一个一个来&#xff…

作者头像 李华
网站建设 2026/6/8 4:16:48

Python 爬虫项目实战:正则表达式筛选网页数字与标题字段

前言 在爬虫数据解析体系中,BeautifulSoup、XPath 依托 DOM 树形结构完成内容定位,二者高度依赖 HTML 标签完整性,一旦网页标签被混淆嵌套、前端页面采用无规范碎片化代码排版,DOM 解析方案会出现大范围解析失效。正则表达式基于…

作者头像 李华
网站建设 2026/6/6 22:50:26

‌智慧校园定制开发:集成商与厂家如何高效协作共创价值

✅作者简介:合肥自友科技 📌核心产品:智慧校园平台(包括教工管理、学工管理、教务管理、考务管理、后勤管理、德育管理、资产管理、公寓管理、实习管理、就业管理、离校管理、科研平台、档案管理、学生平台等26个子平台) 。公司所有人员均有多…

作者头像 李华