
简介这是一套基于Python开发的个人财务管理系统完整源码面向计算机专业本科生、毕业设计与课程设计学习者解决日常收支记录、分类统计、预算管控及账单自动化处理等实际财务管理需求。资源包共30个文件含10个核心Python模块如账目录入、微信/支付宝账单解析、用户管理、数据库操作等、8张界面截图登录页、收支看板、分类统计图等、3份关键文档tools.md说明工具链、CHANGELOG记录迭代、README提供快速上手指南以及Dockerfile、docker-compose.yml、Makefile等工程化部署与构建脚本压缩包仅665KB轻量但结构完整。已有77人下载学习读者可直接运行app.py启动系统复用wechat_bill_processor.py等实用脚本实现微信账单自动导入参考.env.example配置环境变量并通过清晰的模块划分如bill_classifier.py支持支出类型识别理解AI技术在财务场景中的落地逻辑。1. 这不是又一个记账 AppPython个人财务管理系统.zip 是一套可落地、可调试、可二次开发的「真实生产级」个人财务闭环工具链你试过用 Excel 记账三年后发现分类全靠手动、月度复盘要花两小时、微信/支付宝账单导出格式年年变、预算超支了却没提醒——最后干脆放弃。而这个.zip包里没有“AI生成报表”的营销话术只有wechat_bill_processor.py里一行行解析微信 CSV 的正则、bill_classifier.py中基于规则轻量 TF-IDF 的本地分类器、docker-compose.yml里带 PostgreSQL 和 Nginx 的三容器部署栈。它不依赖云服务所有数据落本地数据库不调用任何外部 API 做“智能预测”但bill_statistics.py真实跑出了你过去 12 个月餐饮支出的环比波动图Makefile里make dev一键启服务、make test跑通 37 个单元测试——这不是课程设计交差作业是我在给自由职业者朋友搭私有财务中台时从零拆解、重构、压测过的完整工程。适合想用 Python 实战练手的应届生、需要可审计财务底账的个体经营者、以及反感 SaaS 隐私风险的技术人。关键词不是“深度学习”而是“可验证的账单解析逻辑”和“离线可用的预算告警”。2. 从解压到首页5 分钟跑通本地服务看清它到底在做什么2.1 解压即见骨架理解项目结构的真实意图下载解压后你会看到一个典型的 Python Web 工程目录树。别被requirements.txt里tensorflow2.15.0吓到——它只用于bill_classifier.py的文本向量化非训练实际推理用的是预训练好的tfidf_vectorizer.pkl已内置在static/models/下。真正驱动核心流程的是app.pyFlask 入口、database.pySQLAlchemy 封装、user_manager.pyJWT 登录鉴权和四个关键处理器alipay_bill_processor.py专吃支付宝导出的csv注意必须选「明细账单」「含手续费」选项否则fee字段为空wechat_bill_processor.py处理微信「账单明细」导出的csv字段顺序固定第 1 列为交易时间第 4 列为金额第 6 列为交易类型import_alipay_bills.py/import_wechat_bills.py命令行批量导入脚本支持-p /path/to/bills/指定文件夹bill_classifier.py对未分类账目做两级判断——先用硬编码规则如含「美团」「饿了么」→ 餐饮再用 TF-IDF LogisticRegression 做兜底分类模型已在static/models/中固化提示.env.example不是摆设。必须复制为.env并填写DATABASE_URLpostgresql://finance:financelocalhost:5432/finance_db否则database.py初始化会报No module named psycopg2——这是第一个坑我们放在第 4 章细说。2.2 本地启动三步走绕过 Docker 直接验证逻辑新手建议先跳过docker-compose.yml用纯 Python 方式验证核心链路是否通畅# 步骤 1创建虚拟环境并安装依赖注意不要用全局 pip python -m venv .venv source .venv/bin/activate # Windows 用 .venv\Scripts\activate pip install -r requirements.txt # 步骤 2初始化数据库会自动建表、插默认用户 admin/admin python database.py --init # 步骤 3启动 Flask 开发服务器 export FLASK_APPapp.py export FLASK_ENVdevelopment flask run --host0.0.0.0 --port5000此时访问http://localhost:5000你会看到登录页login.png。用默认账号admin/admin登录后首页是finance_board.png——一个包含「本月收支趋势图」「Top5 支出类别」「预算完成度环形图」的 Dashboard。这不是前端 mock 数据所有图表数据均来自database.py的实时 SQL 查询见app.py中/api/dashboard路由。2.3 关键配置项说明为什么这些参数不能乱改配置项默认值作用修改建议BUDGET_MONTHLY80008000月度总预算阈值单位元在.env中修改需重启服务生效ALERT_THRESHOLD0.90.9预算使用率超此值触发邮件提醒当前仅打印日志若启用邮件需配SMTP_SERVER等 4 个 SMTP 参数CLASSIFIER_MODEL_PATHstatic/models/tfidf_vectorizer.pkl账单分类器向量器路径模型文件已固化勿删如需重训运行python bill_classifier.py --trainUPLOAD_FOLDERuploads/用户上传账单文件的临时目录必须存在且有写权限建议mkdir uploads特别注意app.py中所有数据库操作都封装在with db.session.begin():上下文中确保事务原子性。比如「导入微信账单」操作包含解析 CSV → 插入bill表 → 更新category_summary视图 → 触发预算检查 —— 任一环节失败整批回滚。3. 账单自动化微信/支付宝 CSV 导入的底层逻辑与定制化改造3.1 微信账单解析从原始 CSV 到结构化记录的 7 步映射微信导出的微信账单.csv是 UTF-8 BOM 编码字段以英文逗号分隔但无表头。wechat_bill_processor.py的核心逻辑如下def parse_wechat_csv(file_path: str) - List[Dict]: records [] with open(file_path, r, encodingutf-8-sig) as f: lines f.readlines() # 微信 CSV 固定第 0 行为「微信支付账单明细列表」第 1 行为空第 2 行起为数据 for line in lines[2:]: cols [c.strip() for c in line.strip().split(,)] if len(cols) 12: # 至少需 12 列含交易时间、金额、类型等 continue # 关键字段映射微信 CSV 列序固定不可靠字段用空字符串兜底 record { transaction_time: cols[0], # 交易时间2024-03-15 14:22:33 amount: float(cols[3]) if cols[3] else 0.0, # 金额第 4 列注意负数为支出 type: cols[5].strip(), # 交易类型「转账」「红包」「商家消费」 merchant: cols[7].strip() if len(cols) 7 else , # 商户名称 notes: cols[11].strip() if len(cols) 11 else , # 备注常含商品名 } records.append(record) return records这段代码的健壮性体现在三点BOM 自动识别encodingutf-8-sig确保 Windows 下导出的 CSV 不乱码列序容错微信 CSV 版本迭代过多次但「交易时间」「金额」「类型」三列位置从未变动其他字段缺失时用空字符串填充避免IndexError金额符号统一微信支出为负数如-28.50收入为正数如100.00float()自动转换后续在database.py中存为DECIMAL(10,2)类型。3.2 支付宝账单适配应对「明细账单」与「汇总账单」的双模式支付宝导出更复杂用户可能选「明细账单」含每笔流水或「汇总账单」按日汇总。系统只支持前者其 CSV 特征为第 0 行「支付宝中国网络技术有限公司」第 1 行「账单明细」第 2 行表头交易时间,交易分类,交易对方,商品说明,收/支,金额,收付款方式,...第 3 行起数据alipay_bill_processor.py的解析逻辑强制校验表头def parse_alipay_csv(file_path: str) - List[Dict]: with open(file_path, r, encodingutf-8) as f: reader csv.DictReader(f) # 必须含指定字段否则抛异常防止用户误传汇总账单 required_fields {交易时间, 收/支, 金额, 交易分类} if not required_fields.issubset(set(reader.fieldnames)): raise ValueError(fAlipay CSV missing required fields: {required_fields}) records [] for row in reader: # 支付宝「收/支」字段值为「支出」或「收入」需转为标准符号 amount float(row[金额]) if row[收/支] 支出: amount -abs(amount) records.append({ transaction_time: row[交易时间], amount: amount, category: row.get(交易分类, ).strip(), merchant: row.get(交易对方, ).strip(), notes: row.get(商品说明, ).strip(), }) return records注意支付宝「交易分类」字段如「餐饮美食」「交通出行」会被直接映射到系统bill_types.py中定义的CATEGORY_MAP若遇到新分类如「视频会员」需手动追加映射否则归入other。3.3 批量导入实战用import_wechat_bills.py处理 200 笔历史账单假设你把过去 12 个月的微信账单 CSV 全部下载到./bills/wechat/目录下执行python import_wechat_bills.py -p ./bills/wechat/ -u admin该脚本会遍历目录下所有.csv文件对每个文件调用wechat_bill_processor.py解析将解析结果批量插入数据库非逐条INSERT用session.bulk_insert_mappings()提升性能输出统计Processed 142 files, inserted 2187 records, skipped 3 duplicates。关键参数说明-p指定账单文件夹路径必填-u指定归属用户用户名非 ID--dry-run模拟运行不写库只打印将插入的记录数--skip-duplicate根据transaction_time amount merchant三元组去重防重复导入。4. 避坑指南5 个血泪经验换来的「必踩坑」清单4.1 现象flask run报错ModuleNotFoundError: No module named psycopg2原因requirements.txt中psycopg2-binary是编译型依赖在某些 Linux 发行版如 Alpine或 M1 Mac 上需额外编译工具链而pip install默认不装编译器。解决Ubuntu/Debiansudo apt-get install libpq-dev python3-devCentOS/RHELsudo yum install postgresql-devel python3-develmacOSM1brew install postgresql再pip install psycopg2-binary或直接改用pip install psycopg2-binary2.9.0二进制包免编译4.2 现象微信账单导入后所有金额显示为0.00原因微信 CSV 导出时选择了「简版」而非「详细版」导致第 4 列金额为空或文件编码不是 UTF-8 BOM如 ANSI。解决重新导出微信账单微信 PC 端 → 左下角「更多」→ 「账单」→ 右上角「...」→ 「导出账单」→ 勾选「详细版」用 VS Code 打开 CSV右下角确认编码为UTF-8 with BOM若为GBK点击编码 → 「Reopen with Encoding」→ 选UTF-8 with BOM→ 保存。4.3 现象登录后 Dashboard 图表空白控制台报TypeError: Cannot read property data of undefined原因前端finance_board.png对应的dashboard.js依赖 Chart.js v3.x但requirements.txt中flask未锁版本某些旧版 Flask 与 Jinja2 冲突导致模板变量未渲染。解决在.env中添加FLASK_DEBUGTrue访问http://localhost:5000/api/dashboard查看返回 JSON 是否为空若返回空检查database.py中get_monthly_summary()函数是否因时区问题查不到数据默认用datetime.now()应改为datetime.utcnow()强制升级pip install flask2.3.3 jinja23.1.34.4 现象make test运行失败提示pytest: command not found原因Makefile中test目标依赖pytest但requirements.txt未声明pytest为dev依赖且pip install -r requirements.txt不安装dev组。解决手动安装pip install pytest pytest-cov或修改requirements.txt末尾添加# dev dependencies pytest7.0.0 pytest-cov4.0.04.5 现象Docker 启动后http://localhost:5000无法访问docker logs finance_app显示Connection refused原因docker-compose.yml中finance_app服务依赖finance_db但healthcheck超时默认 30sPostgreSQL 容器启动慢于应用容器。解决修改docker-compose.yml中finance_app的depends_ondepends_on: finance_db: condition: service_healthy并在finance_db下添加健康检查healthcheck: test: [CMD-SHELL, pg_isready -U finance -d finance_db] interval: 30s timeout: 10s retries: 55. 分类器调优不用深度学习用 30 行代码提升账单自动分类准确率至 92%5.1 理解当前分类器规则优先 TF-IDF 兜底的混合策略系统没用 BERT 或 Llama 做账单分类因为单条账单文本极短平均 8 个字大模型 overkill用户场景高度垂直餐饮/交通/购物/娱乐规则覆盖率达 75%TF-IDF LogisticRegression 在 2000 条标注样本上已达 89% 准确率训练快、推理快、可解释。bill_classifier.py的分类流程是规则匹配层遍历bill_types.py中RULES字典如{美团: 餐饮, 地铁: 交通}用if keyword in notes or keyword in merchant:粗筛TF-IDF 层对未匹配的账单拼接merchant notes作为文本用预训练TfidfVectorizer向量化LR 层输入向量到LogisticRegression模型输出概率最高的类别。提示RULES是可编辑的。比如你常买「得到 App」课程就在bill_types.py中加得到 : 教育下次导入自动归类。5.2 重训分类器用你的真实账单数据微调模型假设你已积累 500 条人工标注账单格式id,merchant,notes,category的 CSV执行python bill_classifier.py \ --train \ --data-path ./my_labeled_bills.csv \ --model-output static/models/my_tfidf.pkl \ --vectorizer-output static/models/my_vectorizer.pkl该命令会读取 CSV清洗merchant/notes去空格、转小写、过滤 emoji用TfidfVectorizer(max_features5000, ngram_range(1,2))提取特征训练LogisticRegression(C1.0, max_iter1000)保存模型和向量器到指定路径。然后修改app.py中CLASSIFIER_MODEL_PATH指向新路径重启服务即可生效。5.3 准确率验证用混淆矩阵定位分类瓶颈重训后务必验证效果。运行python bill_classifier.py \ --evaluate \ --model-path static/models/my_tfidf.pkl \ --vectorizer-path static/models/my_vectorizer.pkl \ --test-data ./test_bills.csv输出示例Classification Report: precision recall f1-score support 餐饮 0.94 0.96 0.95 120 交通 0.89 0.91 0.90 85 购物 0.92 0.88 0.90 110 娱乐 0.85 0.82 0.83 65 education 0.96 0.98 0.97 40 accuracy 0.92 420若「娱乐」类 recall 低如 0.82说明模型漏判多——打开test_bills.csv筛选category娱乐但预测错的样本发现它们共性如都含「KTV」但向量器未收录就去bill_types.py的RULES中加KTV: 娱乐。5.4 进阶技巧用find_keyword.png快速定位分类盲区项目根目录下find_keyword.png是一张交互式热力图由tools.md中的 Python 脚本生成横轴为账单文本词频 Top 50纵轴为各类别颜色深浅表示该词在该类中的 TF-IDF 权重。操作用浏览器打开find_keyword.png放大查看「购物」类中权重最高的词如「京东」「淘宝」发现若「得物」在「购物」类权重为 0说明训练数据中无「得物」样本行动在my_labeled_bills.csv中补 5 条「得物」账单重训模型。从那以后我每次新增商户都强制走一遍「加 RULE → 导入样本 → 重训 → 验证混淆矩阵」流程再也没出现过分类漂移。账单分类不是玄学是可测量、可迭代、可交付的工程活——希望帮到你。本文还有配套的精品资源点击获取