把导出的 WhatsApp 聊天记录整理成能读的文字
WhatsApp 会把对话作为一个文本文件交给你,听上去事情已经办完了。打开看看就知道不是。每一行都带着时间戳,格式取决于它是从哪台手机导出的。第一行是一条关于加密的提示。散落在其余部分里的是入群、群名变更、消息撤回标记,还有——只要这个聊天里发过图——大量只写着 <Media omitted> 而没有别的内容的行。
这个页面把它变成一段能读的对话。把 .txt,或者 WhatsApp 用来打包它的 .zip 拖进来,结果就出现在这里。文件在这个浏览器标签页里读取,从不上传。
怎么从 WhatsApp 导出聊天记录
iPhone 和 Android 都一样:打开聊天,点顶部的联系人或群名,往下找到导出聊天,选不含媒体文件。带媒体的选项会把每张照片和每条语音都附上,压缩包会大出几百倍,而对一份文字稿毫无增益——两种方式导出的消息本身完全相同。
结果是一个叫 _chat.txt 的文件,通常装在一个 .zip 里,通过你选的分享方式送出。散装文本文件和压缩包在这里都能用。
为什么时间戳格式才是难点
WhatsApp 的导出没有唯一格式。至少存在两种消息形状,以及数量开放的日期格式,你拿到哪种取决于操作系统和手机的区域设置。
iOS 把时间戳写在方括号里:[12/03/2024, 14:23:01] Name: message。Android 写成裸的,用一个短横线跟消息隔开:12/03/2024, 14:23 - Name: message。秒可能有也可能没有。时钟可能是 24 小时制,也可能是带 AM/PM 的 12 小时制。日期可能日在前、月在前或年在前。分隔符可能是斜杠、点或连字符。
解析器接受两种消息形状,并对日期做宽松匹配,只捕获时间戳而不去把它解释成一个日历日期。最后这个决定是刻意的:03/12/2024 对世界上大多数人是 12 月 3 日,在美国是 3 月 12 日,而文件里没有任何东西告诉你是哪个。猜错就会悄悄把一半人的文字稿标错日期。这里按 WhatsApp 写下的原样显示这个字符串,对当时在场的人来说它没有歧义。
跨行的消息
一条带换行的消息——一份清单、一个地址、一段被人拆开的长文——在导出里表现为一行带时间戳的内容,后面跟着若干既没有时间戳也没有标记的续行。没有分隔符。唯一的信号就是时间戳的缺席。
所以任何不以可识别时间戳开头的行,都会被接到上一条消息上。这是正确的读法,也解释了你可能在更简单的脚本里见过的一种失败:按换行切分文件,你会得到一堆无人认领的碎片,地址和清单像独立消息一样散落在整份文字稿里。
过滤器删掉了什么
默认会去掉两类内容,开关可以把任意一类请回来:
- 系统通知。开头那条加密消息、「X 添加了 Y」「X 已退出」「你删除了这条消息」、群名和群头像变更、安全码变更提示、未接来电记录。在一个活跃的群里,这些可以远远多于真正的消息。
- 媒体占位符。
<Media omitted>、「图片省略」「音频省略」这类本地化变体,以及(file attached)后缀。在一个大家主要发照片的聊天里,这是绝大多数行,而它们不携带任何内容。
如果你关心的正是「东西是什么时候发的」这个规律,就把媒体行留着。如果你需要一份谁在什么时候入群的记录,就把系统通知留着。否则两者都是噪声,删掉它们通常能让文件小一半。
人们拿它来做什么
在退群或换手机之前留一份对话副本。把聊天整理成证据材料——一份干净可读的文字稿远比原始日志有用。把一条长线程喂给模型,让它总结三百条消息中间某处达成的那个决定。在多年的消息里搜一个别处没人写下来的细节。把一个家庭群的历史变成能打印出来的东西。
隐私这一点不是装饰
WhatsApp 的消息在传输中是端到端加密的。你一旦导出,这层保护就结束了:手机上的那个文件是明文,你交给谁,谁就能读。把它上传给一个网页转换器,等于把一路护送它的加密的全部意义作废。
这里什么都不上传。解析器是跑在这个标签页里的 JavaScript;你的导出由浏览器读取、在内存里转换、然后显示出来。没有服务器看到它,所以没有留存政策要读,也没有删除请求要提。关掉标签页,它就没了。
其他平台的导出可以在通用聊天记录导出页处理,那里会自动识别格式。