跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python大前端

基于 Python 解析 HAR 文件生成页面性能测试报告

使用 Python 结合 haralyzer 和 jinja2 库解析浏览器导出的 HAR 文件,自动提取页面加载时间、DNS 耗时、TTFB 等核心性能指标,并渲染生成可视化的 HTML 测试报告。方案涵盖环境安装、HAR 获取步骤、Python 脚本编写及模板配置,支持一键运行排查页面性能瓶颈与异常请求。

未来可期发布于 2026/3/15更新于 2026/10/9104 浏览

基于 Python 解析 HAR 文件生成页面性能测试报告

通过 Python 解析 HAR 文件并自动生成可视化的页面性能测试报告,下面提供一套完整、可直接落地的实现方案,涵盖 HAR 解析、性能指标提取、HTML 报告生成全流程。

一、方案概述

  1. HAR 文件说明:HAR(HTTP Archive)是一种 JSON 格式的文件,用于记录浏览器与服务器之间的 HTTP 请求/响应详情及页面加载性能数据,可通过 Chrome、Firefox 等浏览器的开发者工具获取。
  2. 核心依赖库:
    • haralyzer:专门用于解析 HAR 文件,提取性能指标和请求数据,简化手动解析 JSON 的复杂度。
    • jinja2:轻量级模板引擎,用于快速渲染 HTML 报告,支持自定义报告样式和结构。
    • json:Python 内置库,辅助读取和解析 HAR 文件(haralyzer底层也依赖此库)。
  3. 实现流程:获取 HAR 文件 → Python 解析 HAR → 提取关键性能指标 → 渲染 HTML 模板 → 生成可视化报告。

二、环境准备

先安装所需依赖库,执行以下命令:

pip install haralyzer jinja2 

三、关键步骤实现

步骤 1:获取 HAR 文件(浏览器操作)

以 Chrome 浏览器为例,获取页面 HAR 文件:

  1. 打开 Chrome 浏览器,访问需要测试的页面。
  2. 按 F12 打开开发者工具,切换到 Network 面板。
  3. 勾选面板左上角的 Preserve log(保留日志)。
  4. 刷新页面(或重新加载目标页面),等待所有请求加载完成。
  5. 右键点击 Network 面板中的任意请求,选择 Save all as HAR with content,保存为 .har 格式文件(如 page_perf.har)。
步骤 2:Python 解析 HAR 文件并提取性能指标

编写 Python 脚本,解析 HAR 文件,提取核心页面性能指标(如页面加载时间、DNS 查询时间、TTFB 等)和请求详情。

import json
from haralyzer import HarParser, HarPage
from datetime import datetime

def parse_har_file(har_file_path):
    """ 解析 HAR 文件,提取页面性能指标和请求数据
    :param har_file_path: HAR 文件路径
    :return: 性能指标字典 + 详细请求列表
    """
    # 读取 HAR 文件
    try:
        with open(har_file_path, 'r', encoding='utf-8') as f:
            har_data = json.load(f)
    except FileNotFoundError:
        raise Exception(f"错误:未找到 HAR 文件 {har_file_path}")
    except json.JSONDecodeError:
        raise Exception(f"错误:{har_file_path} 不是合法的 JSON 格式 HAR 文件")
    
    # 初始化 HAR 解析器
    har_parser = HarParser(har_data)
    
    # 获取页面信息(若 HAR 包含多个页面,取第一个页面)
    har_pages = har_parser.pages
    if not har_pages:
        raise Exception("错误:HAR 文件中未包含页面性能数据")
    target_page: HarPage = har_pages[0]
    
    # 提取核心性能指标(单位:毫秒)
    perf_metrics = {
        "页面名称": target_page.page_title or "未命名页面",
        "测试时间": datetime.fromtimestamp(int(target_page.start_time.timestamp())).strftime("%Y-%m-%d %H:%M:%S"),
        "页面加载总时间": round(target_page.page_load_time, 2),  # 页面完全加载时间
        "DNS 查询总时间": round(target_page.dns_time, 2),  # DNS 解析总耗时
        "TCP 连接总时间": round(target_page.tcp_time, 2),  # TCP 三次握手总耗时
        "首字节时间(TTFB)": round(target_page.ttfb, 2),  # 服务器响应首字节时间
        "请求发送时间": round(target_page.send_time, 2),  # 请求数据发送耗时
        "响应接收时间": round(target_page.receive_time, 2),  # 响应数据接收耗时
        "资源加载总时间": round(target_page.ssl_time + target_page.send_time + target_page.receive_time, 2),
        "总请求数": len(target_page.requests),  # 页面总请求数量
        "失败请求数": len([req for req in target_page.requests if req.status_code >= 400]),  # 错误请求数
        "静态资源数(JS/CSS/图片)": len([req for req in target_page.requests if req.resource_type in ["script", "stylesheet", "image"]])
    }
    
    # 提取详细请求列表
    request_details = []
    for req in target_page.requests:
        request_info = {
            "请求 URL": req.url,
            "请求方法": req.method,
            "状态码": req.status_code,
            "资源类型": req.resource_type or "unknown",
            "请求耗时(ms)": round(req.time, 2),
            "DNS 耗时(ms)": round(req.dns_time, 2),
            "TCP 耗时(ms)": round(req.tcp_time, 2),
            "TTFB(ms)": round(req.ttfb, 2),
            "响应大小(B)": req.response_size or 0
        }
        request_details.append(request_info)
    return perf_metrics, request_details
步骤 3:使用 Jinja2 渲染 HTML 报告模板
  1. 先创建 HTML 模板文件(命名为 perf_report_template.html),定义报告样式和结构:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>{{ perf_metrics.页面名称 }} - 性能测试报告</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; font-family: "Microsoft YaHei", sans-serif; }
        .container { width: 95%; margin: 20px auto; }
        .report-header { text-align: center; padding: 15px; background-color: #f5f5f5; border-radius: 5px; margin-bottom: 20px; }
        .metrics-card { background-color: #f8f9fa; padding: 20px; border-radius: 5px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
        .metrics-card h2 { color: #2c3e50; margin-bottom: 15px; border-bottom: 2px solid #3498db; padding-bottom: 10px; }
        .metrics-table { width: 100%; border-collapse: collapse; margin-top: 10px; }
        .metrics-table th, .metrics-table td { border: 1px solid #ddd; padding: 12px; text-align: left; }
        .metrics-table th { background-color: #3498db; color: white; font-weight: bold; }
        .metrics-table tr:nth-child(even) { background-color: #f2f2f2; }
        .warning { color: #e67e22; font-weight: bold; }
        .error { color: #e74c3c; font-weight: bold; }
    </style>
</head>
<body>
    <div class="container">
        <div class="report-header">
            <h1>{{ perf_metrics.页面名称 }} - 页面性能测试报告</h1>
            <p>生成时间:{{ generate_time }} | 测试时间:{{ perf_metrics.测试时间 }}</p>
        </div>
        <!-- 核心性能指标展示 -->
        <div class="metrics-card">
            <h2>一、核心性能指标</h2>
            <table class="metrics-table">
                <thead>
                    <tr>
                        <th>性能指标</th>
                        <th>数值</th>
                        <th>单位</th>
                        <th>说明</th>
                    </tr>
                </thead>
                <tbody>
                    <tr><td>页面加载总时间</td><td>{{ perf_metrics.页面加载总时间 }}</td><td>毫秒(ms)</td><td>页面从开始加载到完全渲染完成的总耗时</td></tr>
                    <tr><td>DNS 查询总时间</td><td>{{ perf_metrics.DNS 查询总时间 }}</td><td>毫秒(ms)</td><td>域名解析的总耗时,越小表示解析越快</td></tr>
                    <tr><td>TCP 连接总时间</td><td>{{ perf_metrics.TCP 连接总时间 }}</td><td>毫秒(ms)</td><td>TCP 三次握手的总耗时,反映网络连接效率</td></tr>
                    <tr><td>首字节时间(TTFB)</td><td>{{ perf_metrics.首字节时间(TTFB) }}</td><td>毫秒(ms)</td><td>从请求发送到接收服务器首个字节的时间,反映服务器响应速度</td></tr>
                    <tr><td>总请求数</td><td>{{ perf_metrics.总请求数 }}</td><td>个</td><td>页面加载的所有 HTTP/HTTPS 请求数量</td></tr>
                    <tr><td>失败请求数</td><td class="{% if perf_metrics.失败请求数 > 0 %}error{% endif %}">{{ perf_metrics.失败请求数 }}</td><td>个</td><td>状态码≥400 的异常请求数量,理想值为 0</td></tr>
                    <tr><td>静态资源数(JS/CSS/图片)</td><td>{{ perf_metrics.静态资源数(JS/CSS/图片) }}</td><td>个</td><td>页面加载的核心静态资源数量</td></tr>
                </tbody>
            </table>
        </div>
        <!-- 详细请求列表展示 -->
        <div class="metrics-card">
            <h2>二、详细请求列表</h2>
            <table class="metrics-table">
                <thead>
                    <tr>
                        <th>请求 URL</th>
                        <th>请求方法</th>
                        <th>状态码</th>
                        <th>资源类型</th>
                        <th>请求耗时(ms)</th>
                        <th>DNS 耗时(ms)</th>
                        <th>TCP 耗时(ms)</th>
                        <th>TTFB(ms)</th>
                        <th>响应大小(B)</th>
                    </tr>
                </thead>
                <tbody>
                    {% for req in request_details %}
                    <tr>
                        <td>{{ req.请求 URL }}</td>
                        <td>{{ req.请求方法 }}</td>
                        <td class="{% if req.状态码 >= 400 %}error{% endif %}">{{ req.状态码 }}</td>
                        <td>{{ req.资源类型 }}</td>
                        <td>{{ req.请求耗时(ms) }}</td>
                        <td>{{ req.DNS 耗时(ms) }}</td>
                        <td>{{ req.TCP 耗时(ms) }}</td>
                        <td>{{ req.TTFB(ms) }}</td>
                        <td>{{ req.响应大小(B) }}</td>
                    </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</body>
</html>
  1. 编写 Python 脚本,加载模板并生成最终 HTML 报告:
from jinja2 import Environment, FileSystemLoader
import os
from datetime import datetime

def generate_perf_report(har_file_path, output_report_path=None):
    """ 一键生成页面性能测试 HTML 报告
    :param har_file_path: HAR 文件路径
    :param output_report_path: 输出报告路径(默认:当前目录 + 页面名称 + _perf_report.html)
    :return: 生成的报告路径
    """
    # 1. 解析 HAR 文件
    perf_metrics, request_details = parse_har_file(har_file_path)
    
    # 2. 配置 Jinja2 模板环境
    # 获取当前目录(模板文件需与脚本在同一目录)
    current_dir = os.path.dirname(os.path.abspath(__file__))
    env = Environment(loader=FileSystemLoader(current_dir))
    
    # 加载 HTML 模板
    template = env.get_template("perf_report_template.html")
    
    # 3. 准备模板渲染数据
    render_data = {
        "perf_metrics": perf_metrics,
        "request_details": request_details,
        "generate_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    }
    
    # 4. 确定输出报告路径
    if not output_report_path:
        page_name = perf_metrics["页面名称"].replace("/", "_").replace("\\", "_").replace(":", "_")
        output_report_path = f"{page_name}_perf_report.html"
    
    # 5. 渲染并生成 HTML 报告
    with open(output_report_path, 'w', encoding='utf-8') as f:
        f.write(template.render(render_data))
    return output_report_path

# 主函数:一键执行
if __name__ == "__main__":
    # 配置参数:HAR 文件路径(替换为你的 HAR 文件路径)
    HAR_FILE_PATH = "page_perf.har"  # 本地 HAR 文件
    # 可选:指定输出报告路径
    # OUTPUT_REPORT_PATH = "my_page_perf_report.html"
    try:
        # 生成报告
        report_path = generate_perf_report(HAR_FILE_PATH)
        # report_path = generate_perf_report(HAR_FILE_PATH, OUTPUT_REPORT_PATH)
        print(f"成功!页面性能测试报告已生成:{os.path.abspath(report_path)}")
    except Exception as e:
        print(f"失败:{e}")

四、一键运行与使用

1. 文件目录结构

确保文件摆放如下:

├── page_perf.har      # 你从浏览器导出的 HAR 文件
├── perf_report_template.html  # HTML 模板文件
└── har_perf_report.py # Python 脚本文件
2. 执行脚本
  1. 修改 har_perf_report.py 中的 HAR_FILE_PATH 为你的 HAR 文件名称(如 page_perf.har)。
  2. 执行成功后,当前目录会生成 .html 格式的性能报告(如 XXX_perf_report.html)。

在终端执行 Python 脚本:

python har_perf_report.py 
3. 查看报告

双击生成的 HTML 报告文件,用任意浏览器打开,即可查看:

  • 核心性能指标(页面加载时间、DNS/TCP 耗时、TTFB 等)。
  • 所有请求的详细信息(URL、状态码、耗时、资源类型等)。
  • 异常请求(状态码≥400)会用红色标注,便于快速排查问题。

五、报告关键指标解读

性能指标含义与优化方向
页面加载总时间页面完全加载耗时,越小越好;优化方向:减少资源体积、开启缓存、懒加载。
DNS 查询时间域名解析耗时,优化方向:使用 DNS 缓存、选择优质 DNS 服务商、减少域名数量。
TCP 连接时间TCP 握手耗时,优化方向:使用 HTTP/2/HTTP/3、开启 TCP 复用、缩短网络链路。
TTFB(首字节时间)服务器响应速度,优化方向:优化服务器接口、使用 CDN、减少后端数据库查询耗时。
失败请求数异常请求数量,理想值为 0;需排查 4xx/5xx 错误(如接口异常、资源不存在)。
总请求数请求数量越多,加载越慢;优化方向:资源合并(JS/CSS 合并)、雪碧图、减少冗余请求。

六、扩展优化

  1. 支持多页面 HAR:修改脚本,遍历 har_parser.pages,为每个页面生成独立报告。
  2. 增加性能阈值判断:在模板中添加阈值配置(如页面加载时间>3000ms 标红警告)。
  3. 导出 Excel 报告:结合 pandas 库,将性能数据导出为 Excel 格式,方便批量统计。
  4. 添加图表可视化:在 HTML 模板中引入 ECharts,生成请求耗时分布、资源类型占比等图表。
总结
  1. 核心流程:HAR 文件获取(浏览器)→ Python 解析(haralyzer)→ 指标提取 → Jinja2 渲染 HTML 报告。
  2. 关键依赖:haralyzer 简化 HAR 解析,jinja2 实现灵活的 HTML 报告定制。
  3. 一键使用:替换 HAR 文件路径,执行脚本即可生成可视化报告,快速排查页面性能瓶颈。

目录

  1. 基于 Python 解析 HAR 文件生成页面性能测试报告
  2. 一、方案概述
  3. 二、环境准备
  4. 三、关键步骤实现
  5. 步骤 1:获取 HAR 文件(浏览器操作)
  6. 步骤 2:Python 解析 HAR 文件并提取性能指标
  7. 步骤 3:使用 Jinja2 渲染 HTML 报告模板
  8. 主函数:一键执行
  9. 四、一键运行与使用
  10. 1. 文件目录结构
  11. 2. 执行脚本
  12. 3. 查看报告
  13. 五、报告关键指标解读
  14. 六、扩展优化
  15. 总结

更多推荐文章

查看全部
  • AIGC 音频平台强制水印策略与 AudioSeal 实现方案
  • Python tkinter 核心组件 IntVar() 用法详解
  • 2025 年 12 月 GESP C++ 一级真题解析
  • 近五年微/纳米机器人赋能肿瘤精准治疗:聚焦 GBM
  • 初识 AI 大语言模型:概念、原理与能力
  • BFS 实现 FloodFill 算法及经典题目解析
  • npm 安装 OpenClaw 遇到 Git 错误及权限问题处理
  • Runway Gen-2 发布运动笔刷功能,支持图像局部动态控制
  • 程序员接单兼职平台盘点与选择指南
  • Spring Boot 2.7.18 至 3.5.8 版本升级避坑指南
  • Python 爬虫基础与实战指南
  • Ubuntu 部署 OpenClaw 完整指南
  • 10 分钟部署本地大模型知识库:Ollama 与 Dify 环境搭建
  • nanobot 本地部署指南:支持 Web、CLI 与 QQ 多通道统一调度
  • IntelliJ IDEA 中 GitHub Copilot 安装与实战技巧
  • 深度学习模型优化策略与实战调参
  • Llama3 + Web UI + Open Interpreter 本地部署与使用指南
  • Llama-3.2-3B 部署案例:Ollama 镜像免配置与 Mac M1/M2 原生运行实测
  • Pix4Dmapper 处理大疆无人机影像数据实战指南
  • OpenClaw 公网访问配置指南:使用 cpolar 内网穿透实现远程 AI 服务

相关免费在线工具

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online