第 17 章 · 毕业项目:自动化脚本(日志分析 / CSV)
本章目标:综合运用 ch02~ch16 技能(含 ch07 魔法方法、ch12~ch14 并发),独立完成 shop-demo 运营日报自动化 毕业项目:读取访问日志与订单 CSV,生成统计报表与异常告警;按 100 分验收表 自评与提交;形成可放入作品集的项目说明(README)。
学时建议:6~8 小时(含编码、测试与文档)
前置:完成 ch01~ch16 全部练习;已配置 py-learn 或项目 .venv。
17.1 项目背景
shop-demo 是一家虚构在线书店。运营同学每天需要:
- 分析 Web 访问日志,找出慢请求与错误状态码;
- 汇总订单 CSV,计算销售额、客单价与 Top 商品;
- 将结果输出为 控制台摘要 + report.txt + summary.csv。
本项目不连接真实生产系统,所有数据均为本地样本文件。
17.2 项目目标(交付物)
| 序号 | 交付物 | 说明 |
|---|---|---|
| 1 | shop_report.py | 主入口,支持命令行参数 |
| 2 | data/access.log | 样本访问日志(≥20 行) |
| 3 | data/orders.csv | 样本订单(≥15 行) |
| 4 | output/report.txt | 人类可读日报 |
| 5 | output/summary.csv | 结构化汇总 |
| 6 | README.md | 运行说明与功能列表 |
| 7 | requirements.txt | 依赖(若有) |
推荐目录:
~/python-learn/shop-demo-graduation/
├── shop_report.py
├── lib/
│ ├── log_parser.py
│ ├── order_stats.py
│ └── report_writer.py
├── data/
│ ├── access.log
│ └── orders.csv
├── output/ # 运行后生成
├── tests/ # 可选
├── requirements.txt
└── README.md
17.3 功能需求
17.3.1 日志分析(40 分相关)
- 解析每行格式(与 ch09 一致):
2026-08-19 10:32:01 GET /books status=200 ms=45
2026-08-19 10:33:12 POST /cart status=500 ms=230
- 统计:总请求数、各
status计数、平均ms; - 列出
ms >= 100的慢请求(路径、耗时); - 列出
status >= 400的错误请求。
17.3.2 订单 CSV(40 分相关)
表头示例:
order_id,user,sku,title,qty,price,order_date
ORD-1001,user-demo,BK-001,Python 基础,2,59.9,2026-08-19
- 订单总金额、订单数、客单价;
- 按
sku汇总销量与销售额,输出 Top 3 商品; - 日期范围(最早~最晚订单日)。
17.3.3 报告输出(20 分相关)
report.txt:分段标题、关键数字、慢请求与错误列表;summary.csv:至少含metric,value两列,如total_sales,1234.56;- 控制台打印一行「报告已生成:...」。
17.4 命令行接口
python shop_report.py \
--log data/access.log \
--orders data/orders.csv \
--out-dir output \
--slow-ms 100
| 参数 | 默认 | 说明 |
|---|---|---|
--log | data/access.log | 日志路径 |
--orders | data/orders.csv | 订单 CSV |
--out-dir | output | 输出目录 |
--slow-ms | 100 | 慢请求阈值 |
使用 argparse(标准库)实现。
17.5 参考实现骨架
# shop_report.py
import argparse
from pathlib import Path
from lib.log_parser import analyze_log
from lib.order_stats import analyze_orders
from lib.report_writer import write_report
def main():
parser = argparse.ArgumentParser(description="shop-demo 运营日报")
parser.add_argument("--log", default="data/access.log")
parser.add_argument("--orders", default="data/orders.csv")
parser.add_argument("--out-dir", default="output")
parser.add_argument("--slow-ms", type=int, default=100)
args = parser.parse_args()
log_stats = analyze_log(Path(args.log), slow_ms=args.slow_ms)
order_stats = analyze_orders(Path(args.orders))
out = Path(args.out_dir)
out.mkdir(parents=True, exist_ok=True)
write_report(out, log_stats, order_stats)
print(f"报告已生成:{out.resolve()}")
if __name__ == "__main__":
main()
模块拆分体现 ch05 函数化与 ch08 文件处理能力。
17.6 样本数据生成提示
可用脚本批量生成 access.log:
import random
from datetime import datetime, timedelta