爬虫数据导出 Excel:openpyxl 高级用法

在 Python 爬虫开发中,将采集到的数据导出为 Excel 文件是高频需求。基础的 Excel 操作库(如 xlwt)存在行数限制、格式支持差等问题,而 openpyxl 作为专注于 xlsx 格式的高性能库,不仅能突破行数限制,还支持单元格样式、公式、图表等高级功能,是爬虫数据导出的最优选择之一。本文将从实战角度,讲解 openpyxl 的核心高级用法,帮助你优雅地处理爬虫数据的 Excel 导出。

一、openpyxl 核心优势

相比于其他 Excel 操作库,openpyxl 适配爬虫场景的核心优势:

  1. 支持.xlsx格式,无行数限制(xlwt 仅支持.xls,最多 65536 行),适配爬虫海量数据导出;
  2. 支持单元格样式(字体、颜色、对齐)、合并单元格、公式等,可直接生成可视化的分析报表;
  3. 支持读写分离,可增量写入数据,避免内存溢出;
  4. 纯 Python 实现,无需依赖 COM 组件,跨平台兼容性好。

二、环境准备

首先安装 openpyxl 库:

bash

运行

复制代码
pip install openpyxl

三、爬虫数据导出核心高级用法

1. 基础封装:爬虫数据批量写入(增量写入)

爬虫采集数据时,通常是分批获取(如分页爬取),直接一次性写入大列表易导致内存占用过高。以下封装一个增量写入的工具类,每爬取一页数据就写入 Excel,降低内存消耗。

python

运行

复制代码
import openpyxl
from openpyxl.styles import Font, Alignment, PatternFill
from typing import List, Dict

class SpiderExcelExporter:
    def __init__(self, file_path: str, sheet_name: str = "爬虫数据"):
        """
        初始化Excel导出器
        :param file_path: 导出文件路径(如:./spider_data.xlsx)
        :param sheet_name: 工作表名称
        """
        self.file_path = file_path
        self.sheet_name = sheet_name
        # 创建工作簿
        self.workbook = openpyxl.Workbook()
        # 删除默认工作表,创建自定义工作表
        if "Sheet" in self.workbook.sheetnames:
            self.workbook.remove(self.workbook["Sheet"])
        self.worksheet = self.workbook.create_sheet(title=sheet_name)
        # 记录当前写入行号(初始为1,对应Excel第一行)
        self.current_row = 1

    def set_header(self, headers: List[str]):
        """
        设置表头,并添加样式
        :param headers: 表头列表(如:["标题", "链接", "发布时间"])
        """
        if not headers:
            return
        # 表头样式:加粗、居中、浅蓝背景
        header_font = Font(bold=True, size=12)
        header_alignment = Alignment(horizontal="center", vertical="center")
        header_fill = PatternFill(start_color="E6F3FF", end_color="E6F3FF", fill_type="solid")
        
        # 写入表头
        for col, header in enumerate(headers, start=1):
            cell = self.worksheet.cell(row=self.current_row, column=col, value=header)
            cell.font = header_font
            cell.alignment = header_alignment
            cell.fill = header_fill
        # 表头写入后,行号+1
        self.current_row += 1

    def add_data(self, data: List[Dict]):
        """
        增量添加爬虫数据(支持多条)
        :param data: 数据列表,每个元素为字典(键对应表头)
        """
        if not data:
            return
        # 数据样式:居中对齐
        data_alignment = Alignment(horizontal="center", vertical="center")
        # 遍历每条数据
        for item in data:
            # 按表头顺序写入数据(确保字典键与表头一致)
            for col, key in enumerate(self.worksheet[1], start=1):
                cell_value = item.get(key.value, "")  # 按表头键取值,无则为空
                cell = self.worksheet.cell(row=self.current_row, column=col, value=cell_value)
                cell.alignment = data_alignment
            self.current_row += 1

    def auto_adjust_column_width(self):
        """
        自动调整列宽(适配内容长度)
        """
        for column in self.worksheet.columns:
            max_length = 0
            column_letter = column[0].column_letter  # 获取列字母(如A、B)
            for cell in column:
                try:
                    if len(str(cell.value)) > max_length:
                        max_length = len(str(cell.value))
                except:
                    pass
            # 列宽预留2个字符的余量
            adjusted_width = min(max_length + 2, 50)  # 限制最大列宽为50
            self.worksheet.column_dimensions[column_letter].width = adjusted_width

    def save(self):
        """保存Excel文件"""
        # 自动调整列宽后保存
        self.auto_adjust_column_width()
        self.workbook.save(self.file_path)
        print(f"数据已导出至:{self.file_path}")

# #################### 用法示例 ####################
if __name__ == "__main__":
    # 1. 初始化导出器
    exporter = SpiderExcelExporter("./article_data.xlsx", sheet_name="文章数据")
    
    # 2. 设置表头
    headers = ["标题", "链接", "发布时间", "阅读量"]
    exporter.set_header(headers)
    
    # 3. 模拟爬虫分批获取的数据(实际场景中替换为真实爬取数据)
    page1_data = [
        {"标题": "Python爬虫实战", "链接": "https://example.com/1", "发布时间": "2026-02-01", "阅读量": 1200},
        {"标题": "openpyxl高级用法", "链接": "https://example.com/2", "发布时间": "2026-02-02", "阅读量": 800}
    ]
    page2_data = [
        {"标题": "爬虫反爬策略", "链接": "https://example.com/3", "发布时间": "2026-02-03", "阅读量": 1500},
        {"标题": "Excel数据可视化", "链接": "https://example.com/4", "发布时间": "2026-02-04", "阅读量": 950}
    ]
    
    # 4. 增量添加数据
    exporter.add_data(page1_data)
    exporter.add_data(page2_data)
    
    # 5. 保存文件
    exporter.save()

2. 高级功能 1:合并单元格(适用于分类数据)

爬虫数据常存在分类场景(如按日期 / 分类聚合),合并单元格可提升 Excel 可读性:

python

运行

复制代码
# 在SpiderExcelExporter类中新增方法
def merge_cells(self, start_row: int, end_row: int, start_col: int, end_col: int):
    """
    合并单元格
    :param start_row: 起始行
    :param end_row: 结束行
    :param start_col: 起始列
    :param end_col: 结束列
    """
    self.worksheet.merge_cells(
        start_row=start_row,
        end_row=end_row,
        start_col=start_col,
        end_col=end_col
    )

# 用法示例:合并第1行第1列到第1行第4列(表头合并)
exporter.merge_cells(start_row=1, end_row=1, start_col=1, end_col=4)
exporter.worksheet.cell(row=1, column=1, value="2026年2月文章数据")  # 合并后只需要给左上角单元格赋值

3. 高级功能 2:添加计算公式(自动统计)

导出数据后,可直接添加求和、平均值等公式,无需手动计算:

python

运行

复制代码
# 示例:统计阅读量总和(假设阅读量在D列,数据行是2-5行)
# 写入求和公式到D6单元格
exporter.worksheet.cell(row=6, column=4, value="=SUM(D2:D5)")
# 写入平均值公式到D7单元格
exporter.worksheet.cell(row=7, column=4, value="=AVERAGE(D2:D5)")
# 给公式单元格添加标注
exporter.worksheet.cell(row=6, column=3, value="阅读量总和:")
exporter.worksheet.cell(row=7, column=3, value="平均阅读量:")

4. 高级功能 3:批量设置单元格格式(数字 / 日期)

爬虫采集的数字、日期可能以字符串形式存储,可统一设置单元格格式:

python

运行

复制代码
from openpyxl.styles import numbers

# 设置D列(阅读量)为数字格式
exporter.worksheet.column_dimensions["D"].number_format = numbers.FORMAT_NUMBER
# 设置C列(发布时间)为日期格式
exporter.worksheet.column_dimensions["C"].number_format = numbers.FORMAT_DATE_YYYYMMDD2

5. 高级功能 4:追加写入已有 Excel 文件

若需要向已存在的 Excel 文件追加爬虫数据(如定时爬取增量数据):

python

运行

复制代码
def append_to_existing_file(self, file_path: str, sheet_name: str, data: List[Dict]):
    """
    追加数据到已有Excel文件
    :param file_path: 已有文件路径
    :param sheet_name: 工作表名称
    :param data: 新增数据
    """
    # 加载已有工作簿
    workbook = openpyxl.load_workbook(file_path)
    worksheet = workbook[sheet_name] if sheet_name in workbook.sheetnames else workbook.create_sheet(sheet_name)
    # 获取已有数据的最后一行
    last_row = worksheet.max_row + 1
    # 写入新增数据
    data_alignment = Alignment(horizontal="center", vertical="center")
    for item in data:
        for col, key in enumerate(worksheet[1], start=1):
            cell_value = item.get(key.value, "")
            cell = worksheet.cell(row=last_row, column=col, value=cell_value)
            cell.alignment = data_alignment
        last_row += 1
    # 保存文件
    workbook.save(file_path)

# 用法示例:追加数据到已有的article_data.xlsx
exporter.append_to_existing_file(
    file_path="./article_data.xlsx",
    sheet_name="文章数据",
    data=[{"标题": "新增文章", "链接": "https://example.com/5", "发布时间": "2026-02-05", "阅读量": 700}]
)

四、实战避坑指南

  1. 内存优化 :爬取超 10 万条数据时,避免一次性加载所有数据,改用yield分批生成数据,配合add_data增量写入;
  2. 编码问题 :爬虫数据中的中文需确保为utf-8编码,写入前可通过str(cell_value).encode("utf-8", "ignore").decode("utf-8")处理乱码;
  3. 性能优化 :关闭 Excel 的自动计算功能(workbook.calculation.calc_mode = "manual"),写入完成后再开启,提升大文件写入速度;
  4. 文件锁问题:保存文件前需确保 Excel 文件未被打开,否则会抛出权限异常。

五、总结

openpyxl 的高级用法能让爬虫数据的 Excel 导出从 "简单存储" 升级为 "可视化报表",核心要点:

  1. 增量写入 + 自动列宽调整,适配爬虫海量数据导出,兼顾性能与可读性;
  2. 样式设置、合并单元格、公式计算,可直接生成可分析的 Excel 报表;
  3. 支持追加写入已有文件,适配定时爬取、增量更新的场景。

掌握这些用法后,你可以摆脱 "爬取数据→手动整理 Excel" 的低效流程,实现爬虫数据导出的全自动化、标准化。

相关推荐
reasonsummer2 小时前
【教学类-74-05】20260216剪影马(黑色填充图案转黑线条白填充)
python
查士丁尼·绵2 小时前
通过sdk获取ecs指标
python·sdk
喵手2 小时前
Python爬虫实战:失败重试分级 - DNS/超时/403 分策略处理 + 重试退避等!
爬虫·python·爬虫实战·零基础python爬虫教学·失败重试分级·dns/超时·重试退避
得一录2 小时前
Python 算法高级篇:布谷鸟哈希算法与分布式哈希表
python·算法·aigc·哈希算法
Faker66363aaa2 小时前
基于Cascade-Mask-RCNN和RegNetX-4GF的果蝇检测与识别系统——COCO数据集训练与优化
python
聂 可 以2 小时前
解决Pycharm中(Python)软件包下载速度很慢、甚至下载失败的问题
ide·python·pycharm
七夜zippoe2 小时前
强化学习实战指南:从Q-Learning到PPO的工业级应用
python·openai·超参数调优·q-learning·mdp
JaydenAI2 小时前
[拆解LangChain执行引擎]非常规Pending Write的持久化
python·langchain
MoonPointer-Byte2 小时前
【Python实战】我开发了一款“诗意”待办软件:MoonTask(附源码+工程化思路)
开发语言·python·custom tkinter