微信聊天记录导出全攻略:HTML、Word、CSV三种格式与年度报告生成
简介这是一套面向开发者与数据分析爱好者的微信聊天记录处理工具包基于ChatGPT等大语言模型进行二次开发也支持接入私有部署模型帮助用户将零散的聊天数据转化为可长期保存、可深度分析的结构化资料。资源包共256个文件以103个Python源码为核心辅以61张PNG图示、43个SVG矢量图、18个HTML页面及18份Markdown说明文档另有JSON配置、proto协议文件与少量可执行程序整体约25.4MB代码注释清晰便于二次修改与功能扩展。项目可实现聊天记录导出为HTML、Word、CSV等多种格式并据此生成年度聊天报告涵盖词云、图表可视化等分析模块适合希望掌握LLM应用落地、数据清洗与可视化呈现的中级开发者参考。目前已有382人学习下载配套环境搭建教程可降低上手门槛帮助读者快速跑通从数据提取到报告生成的完整链路。1. 聊天记录导出这件事为什么值得认真做一次微信聊天记录默认躺在手机或电脑的加密数据库里官方只提供「迁移到另一台设备」这种半封闭方案一旦换机、清缓存、卸载重装几年的对话可能直接归零。我见过太多人等到手机丢了才想起来「那些记录还能找回来吗」答案是大概率不能。这份资源包解决的正是这个痛点把微信聊天记录提取出来导出成 HTML、Word、CSV 三种格式永久保存还能基于记录生成年度聊天报告。它适合两类人——一类是纯粹想备份重要对话的普通用户另一类是想拿聊天数据做分析、做可视化、甚至喂给 LLM 做个人语料的技术从业者。HTML 适合浏览归档Word 适合打印或正式存档CSV 则是数据分析的通用入口。三种格式覆盖了「看、存、算」三个场景这是我觉得这个包设计得比较务实的地方。2. 导出前的技术底牌数据库解密与数据定位2.1 微信聊天记录到底存在哪PC 端微信的聊天数据默认存放在Documents\WeChat Files\目录下每个微信号对应一个以 wxid 开头的文件夹。进入后能看到Msg目录里面是.db后缀的 SQLite 数据库文件。手机端则更复杂Android 需要 root 或借助本地备份提取iOS 需要通过 iTunes 备份后解析备份文件。这个资源包主要针对 PC 端场景因为 PC 端的数据文件结构最清晰、最容易操作。常见做法是先用工具定位到Msg\Multi目录下的MSG0.db到MSG9.db这些是分片存储的消息主库。另外还有Media目录存放图片视频、File目录存放文件传输记录。理解这个目录结构很重要因为后面导出时你需要告诉脚本去哪里读数据。注意操作前务必把整个WeChat Files文件夹复制一份到其他盘所有后续操作都在副本上进行避免误操作导致原始数据损坏。2.2 数据库解密为什么不能直接打开 .db 文件直接用 SQLite 客户端打开MSG0.db会提示「file is not a database」因为微信对这些文件做了加密。PC 端微信的加密方式是基于设备信息的 AES 加密密钥与登录设备绑定。解密需要拿到密钥而密钥的获取方式取决于微信版本。对于较老版本3.x 早期密钥可以通过内存搜索工具从微信进程空间中提取。较新版本3.9 以后密钥获取难度增加通常需要借助专门的解密工具。这个资源包里附带的教程应该覆盖了对应版本的操作流程。解密后的数据库就是标准 SQLite 格式可以用任何 SQLite 工具打开。# 解密后的数据库可以用 sqlite3 直接查看表结构 sqlite3 MSG0.db .tables # 典型输出MSG Contact ChatRoom Media ...逻辑说明.tables命令列出所有表名MSG表是核心消息表Contact存联系人信息ChatRoom存群聊信息。参数方面如果你的数据库分片较多需要对每个MSG*.db都执行解密导出脚本通常会遍历整个目录。2.3 消息表结构导出脚本要读哪些字段解密后的MSG表字段很多但导出真正需要的是这几个核心列字段名含义导出时的处理localId本地消息 ID用于排序和去重CreateTime消息时间戳转换为可读日期Type消息类型区分文本/图片/语音/文件IsSender是否自己发送区分左右对话气泡StrContent文本内容直接导出StrTalker对话对象 wxid关联联系人表获取昵称BytesExtra附加数据图片/文件路径解析导出脚本的核心逻辑就是SELECT这些字段然后按StrTalker分组、按CreateTime排序再渲染成目标格式。理解这张表的结构后面不管你是改脚本还是自己写导出工具都不会迷路。3. 三种导出格式的实操HTML、Word、CSV 怎么选怎么用3.1 HTML 导出最适合浏览归档的格式HTML 是三种格式里最适合「看」的。导出后的 HTML 文件保留了聊天气泡样式左右分明图片和表情能内嵌显示打开浏览器就能像翻聊天窗口一样回顾对话。资源包里的 HTML 导出通常会把每个对话对象生成一个独立页面再通过一个索引页串联起来。# HTML 导出核心逻辑简化示意 import sqlite3, html, datetime def export_html(db_path, talker_wxid, output_path): conn sqlite3.connect(db_path) cur conn.cursor() cur.execute( SELECT CreateTime, IsSender, StrContent, Type FROM MSG WHERE StrTalker ? ORDER BY CreateTime ASC , (talker_wxid,)) rows cur.fetchall() with open(output_path, w, encodingutf-8) as f: f.write(!DOCTYPE htmlhtml langzh-cnhead) f.write(meta charsetutf-8title聊天记录/title) f.write(style.msg{max-width:70%;margin:8px;padding:10px; border-radius:8px;word-wrap:break-word} .me{background:#95ec69;margin-left:auto} .other{background:#fff}/style/headbody) for ts, is_sender, content, msg_type in rows: t datetime.datetime.fromtimestamp(ts).strftime(%Y-%m-%d %H:%M) cls me if is_sender else other safe html.escape(content or [非文本消息]) f.write(fdiv classmsg {cls}small{t}/smallbr{safe}/div) f.write(/body/html) conn.close()逻辑说明脚本先按StrTalker过滤出目标对话按时间升序排列然后逐条生成div气泡。IsSender决定气泡靠左还是靠右CSS 里用margin-left:auto实现右对齐。参数方面output_path建议按「昵称_日期.html」命名方便后续检索。如果消息量大单文件可能超过几十 MB浏览器打开会卡常见做法是按月份拆分成多个 HTML 文件再生成一个目录页。提示导出的 HTML 里如果包含图片需要确保图片路径正确。资源包通常会把图片复制到同级images目录用相对路径引用这样整个文件夹拷走也不会丢图。3.2 Word 导出正式存档和打印的首选Word 格式适合需要打印、提交或正式归档的场景。相比 HTMLWord 的优势在于排版稳定、兼容性好发给不熟悉技术的人也能直接打开。导出 Word 一般用python-docx库把每条消息写成一个段落自己发送的用右对齐对方发送的用左对齐。from docx import Document from docx.enum.text import WD_ALIGN_PARAGRAPH import sqlite3, datetime def export_word(db_path, talker_wxid, output_path): doc Document() doc.add_heading(聊天记录导出, level1) conn sqlite3.connect(db_path) cur conn.cursor() cur.execute( SELECT CreateTime, IsSender, StrContent FROM MSG WHERE StrTalker ? ORDER BY CreateTime ASC , (talker_wxid,)) for ts, is_sender, content in cur.fetchall(): t datetime.datetime.fromtimestamp(ts).strftime(%Y-%m-%d %H:%M) p doc.add_paragraph() p.alignment WD_ALIGN_PARAGRAPH.RIGHT if is_sender else WD_ALIGN_PARAGRAPH.LEFT run p.add_run(f[{t}]\n{content or [非文本消息]}) run.font.size 10 doc.save(output_path) conn.close()逻辑说明python-docx的add_paragraph创建段落alignment控制左右对齐。每条消息前加时间戳方便定位。参数方面font.size设为 10 磅可以在保证可读性的同时压缩篇幅。如果消息量超过几千条Word 文件会变得很大且打开缓慢建议按对话对象或按月份拆分导出。注意Word 导出时如果消息内容包含特殊字符如 emojipython-docx可能报编码错误。常见做法是先把内容用content.encode(utf-8, ignore).decode(utf-8)清洗一遍。3.3 CSV 导出数据分析的通用入口CSV 是三种格式里最「素」的但也是最有扩展性的。导出成 CSV 后你可以用 Excel 做透视表、用 Python 做统计分析、用 SQL 做关联查询甚至导入到 BI 工具里做可视化。CSV 导出的字段设计直接决定了后续分析的便利程度。import sqlite3, csv, datetime def export_csv(db_path, output_path): conn sqlite3.connect(db_path) cur conn.cursor() cur.execute( SELECT m.CreateTime, c.NickName, m.IsSender, m.Type, m.StrContent FROM MSG m LEFT JOIN Contact c ON m.StrTalker c.UserName ORDER BY m.CreateTime ASC ) with open(output_path, w, newline, encodingutf-8-sig) as f: writer csv.writer(f) writer.writerow([时间, 对话对象, 是否自己, 消息类型, 内容]) for ts, nick, is_sender, msg_type, content in cur.fetchall(): t datetime.datetime.fromtimestamp(ts).strftime(%Y-%m-%d %H:%M:%S) writer.writerow([t, nick or , 是 if is_sender else 否, msg_type, content or ]) conn.close()逻辑说明这里用LEFT JOIN关联Contact表获取昵称比只导出 wxid 可读性好得多。encodingutf-8-sig是为了让 Excel 直接打开时不乱码这个细节很多人会忽略。参数方面msg_type保留原始数字类型方便后续按类型筛选比如只看文本消息做词频分析。如果要做年度报告CSV 就是数据源后面的统计和图表都从这里出发。4. 年度聊天报告从 CSV 到可视化分析的完整链路4.1 数据清洗先解决时间戳和消息类型拿到 CSV 后第一步不是急着画图而是清洗。常见问题有三个时间戳是 Unix 格式需要转换、非文本消息图片、语音、红包需要标记或剔除、群聊消息需要区分发送者。清洗后的数据才是可信的分析基础。import pandas as pd df pd.read_csv(chat_export.csv, encodingutf-8-sig) df[时间] pd.to_datetime(df[时间]) df[月份] df[时间].dt.to_period(M) df[小时] df[时间].dt.hour df[是否自己] df[是否自己].map({是: True, 否: False}) # 只保留文本消息做内容分析 text_df df[df[消息类型] 1].copy() text_df[字数] text_df[内容].str.len()逻辑说明to_period(M)生成月份周期方便按月聚合。dt.hour提取小时用于分析聊天时段分布。消息类型 1是文本消息的约定值不同微信版本可能略有差异需要根据实际数据确认。清洗后的text_df就是后续所有分析的输入。4.2 统计维度消息量、时段、关键词、互动频率年度报告的核心统计维度通常包括每月消息总量趋势、24 小时聊天时段分布、高频词 Top 20、与每个对话对象的互动次数排名。这些统计用 pandas 几行代码就能跑出来。# 每月消息量 monthly df.groupby(月份).size() # 聊天时段分布 hourly df.groupby(小时).size() # 高频词简单按字符切分中文建议用 jieba import jieba from collections import Counter words [] for content in text_df[内容].dropna(): words.extend(jieba.lcut(content)) word_freq Counter([w for w in words if len(w) 1]).most_common(20) # 互动对象排名 talker_rank df[df[是否自己] False].groupby(对话对象).size().sort_values(ascendingFalse)逻辑说明groupby加size()是最基础的聚合方式。中文分词用jieba过滤掉单字可以减少噪音。talker_rank统计的是对方发给你的消息数反映谁最常主动找你。这些统计结果可以直接输出成表格也可以进一步用 matplotlib 或 pyecharts 生成图表。4.3 生成报告把统计结果组装成可读文档统计跑完后最后一步是把结果组装成一份可读的报告。可以用 Word 模板填充也可以生成 HTML 报告。资源包里通常提供了一份报告模板你只需要把统计数字和图表替换进去。from docx import Document from docx.shared import Inches doc Document() doc.add_heading(年度聊天报告, level0) doc.add_heading(消息总量, level1) doc.add_paragraph(f全年共导出 {len(df)} 条消息其中文本消息 {len(text_df)} 条。) doc.add_heading(聊天时段分布, level1) doc.add_paragraph(f最活跃时段{hourly.idxmax()} 点共 {hourly.max()} 条消息。) doc.add_heading(高频词 Top 10, level1) for word, count in word_freq[:10]: doc.add_paragraph(f{word}{count} 次, styleList Bullet) doc.save(年度报告.docx)逻辑说明add_heading创建标题层级add_paragraph写入正文。hourly.idxmax()返回消息量最大的小时。这份报告可以继续扩展比如加入每月趋势折线图、对话对象词云等。参数方面styleList Bullet让高频词以列表形式呈现比纯段落更清晰。5. 避坑与排查导出过程中最容易翻车的五个地方5.1 解密后数据库打开报错「file is not a database」现象用 SQLite 工具打开解密后的.db文件提示不是有效数据库。原因通常是解密不完整或密钥错误也可能是文件本身损坏。解决方法是重新执行解密流程确认密钥与当前微信版本匹配如果仍然失败尝试用副本重新解密避免在原文件上反复操作。5.2 导出的 HTML 图片全部裂开现象HTML 打开后文字正常但图片位置显示破损图标。原因是图片路径是绝对路径换电脑后路径失效。解决方法是导出时把图片复制到 HTML 同级目录用相对路径引用或者直接把图片转成 base64 内嵌到 HTML 里代价是文件体积会明显增大。5.3 CSV 用 Excel 打开中文乱码现象CSV 文件双击用 Excel 打开中文全部变成乱码。原因是 Excel 默认按 GBK 编码读取 CSV而文件是 UTF-8。解决方法是在导出时使用utf-8-sig编码这个 BOM 头会让 Excel 正确识别编码。如果已经导出了用记事本打开另存为 ANSI 编码也能临时救急。5.4 消息顺序错乱时间对不上现象导出的聊天记录里消息顺序和微信里看到的不一致。原因是MSG表按分片存储不同分片的时间戳可能有交叉单纯按localId排序不可靠。解决方法是严格按CreateTime排序并且在查询时加上ORDER BY CreateTime ASC, localId ASC做二级排序。5.5 导出到一半脚本崩溃提示内存不足现象消息量大的对话导出时脚本卡死或报 MemoryError。原因是把所有消息一次性读进内存再处理。解决方法是改用游标逐条读取、逐条写入或者按月份分批导出。对于超过 10 万条消息的对话分批是唯一可行的方案。6. 进阶技巧把聊天记录变成可检索的个人语料库导出成 CSV 只是第一步真正让数据产生价值的是后续的检索和利用。我自己的习惯是把 CSV 导入 SQLite建全文索引然后用 SQL 做任意维度的查询。这样比在 Excel 里翻找高效得多也为后续接入 LLM 做个人语料库打好了基础。-- 建表并导入 CSV 数据 CREATE TABLE chat ( id INTEGER PRIMARY KEY AUTOINCREMENT, time TEXT, talker TEXT, is_self INTEGER, msg_type INTEGER, content TEXT ); -- 建全文索引需要 FTS5 支持 CREATE VIRTUAL TABLE chat_fts USING fts5( content, talker, contentchat, content_rowidid ); -- 检索包含特定关键词的对话 SELECT time, talker, content FROM chat_fts WHERE chat_fts MATCH 项目 进度 ORDER BY time DESC LIMIT 20;逻辑说明FTS5 是 SQLite 的全文索引模块MATCH语法支持多关键词组合查询。contentchat表示索引内容来自chat表不额外存储一份数据。参数方面LIMIT 20控制返回条数避免一次拉太多。建好索引后几百万条消息里搜关键词也是毫秒级返回。如果你想把聊天记录作为个人语料喂给 LLMCSV 里的content列就是现成的文本源。常见做法是按对话对象或时间段筛选出高质量对话清洗掉短消息和表情导出成纯文本或 JSONL 格式再用嵌入模型建向量索引。这样你就能用自然语言检索自己过去说过的话相当于给记忆装了一个搜索引擎。提示做语料库时注意隐私边界导出的数据只在自己可控的环境里使用不要上传到不可信的第三方服务。从那以后我每次导出聊天记录都会先复制一份原始数据库副本再跑解密和导出脚本最后把 CSV 导入 SQLite 建索引。这套流程走下来几年的对话就变成了一个随时可查的个人数据库。希望帮到你。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联
返回资讯列表 →