基于微信聊天记录的日历热力图 🔥🔥🔥,纪念日给女朋友一个惊喜 🚀🚀🚀

基于微信聊天记录的日历热力图 🔥🔥🔥,纪念日给女朋友一个惊喜 🚀🚀🚀

和女票在一起 1000 天了,上次她给我看她朋友圈有朋友做了一个微信聊天记录的热力图,觉得很有意思,这次便想着也给她做一个。本以为这玩意应该有开源的项目可以直接复用,但使用热力图微信聊天记录这样的关键字并没有找到,特别是微信聊天记录的提取,还是费了不少时间。便想着写一篇博客记录一下,方便大家参考。

制作这样的热力图,一共分为 4 步:

  1. 提取微信聊天记录
  2. 分析数据库,以天为单位获取聊天记录数
  3. 生成热力图
  4. 后期加工

接下来我会一步一步分析,帮助大家制作自己的热力图。

这是我认为最麻烦的一步。想到提取微信聊天记录,最开始想到的就是使用微信自带的备份,不过这种备份是加密的,而且我搜了下还没见到有方案破解这种备份。博主手机是 iOS,便先尝试搜索 iOS 的解决方案。

幸运的是,iOS 备份中的微信文件,特别是微信聊天记录库都是未加密的,意味着从 iOS 备份中可以直接读取微信聊天记录库,反观 PC 和 Android 中的文件却都是加密的(我猜测可能因为 iOS 作为封闭系统,安全性本来就较高,也获取不到软件数据,所以需要从备份中读取软件数据)。

那么接下来就是先备份你的 iPhone,以 Mac 为例,在 MacOS 10.15 及以上版本中直接使用“访达”,旧版本使用 iTunes 即可。我这里是 MacOS 11,备份时不要勾选“加密本地备份”,点击“立即备份”即可。

我在备份时遇到一些小差错,很久以前我开启过“加密本地备份”,但是这次却没看到被勾上,直到备份完成才发现是一份加密备份。大家备份前可以先点击对勾,确定是否真正开启,如果开启请先关闭。

iOS Backup

备份完成后进入下一步。

虽然 iOS 备份中的微信聊天记录数据库是未加密的,不过备份本身打开后却是一堆以数字命名的文件夹,所有 APP 的文件似乎都被打散了,无法找到微信聊天记录在哪个文件夹。因此需要有方法先把混乱的备份恢复成可以阅读的。

关于 iOS 备份浏览,市面上有很多成熟的软件,比较有名的是 iMazing 和 iPhone Backup Extractor,但他们几乎都只能免费读取,提取则是收费的(免费软件其实我也不放心),在这之前我也搜索过开源方案,但是没找到合适的,自己也没太多时间折腾,最终选择了 iMazing,因为它有位于中国的第三方销售商。

下面是 iOS 备份读取软件 iMazing 读取后的界面:

iMazing Screen Shoot

微信的聊天记录数据库位于 Documents/xxx/DB/*.sqlitexxx 是设备上登录的用户,如果设备上用户少比如我就两个,则可以马上找到那个常用的。进入 DB 目录后,可以发现很多 message_x.sqlite 文件,和一个 WCDB_Contact.sqlite 文件,其中前者里面保存了我们的聊天记录,后者则是联系人。

先安装一个免费的 sqlite 数据库软件 DB Browser for SQLite。安装完成后随便加载一个数据库例如 message_1.sqlite,会发现里面有很多张表,命名为 Chat_balablabalabala,其中每张表存储着你和某个联系人的聊天记录,后面这串字母是该联系人 userName 字段的 MD5 Hash 值,这个字段则位于 WCDB_Contact.sqlite 数据库。

那么首先我们需要打开 WCDB_Contact.sqlite 数据库,找到其中的 Friend 表,下面是我过滤后的 Friend 表:

WeChat Friend Table

上面我标出了三个红框,从左到右,第一个是前面提到的 userName 列,第二个是 DB Browser 提供的表搜索功能,第三个是 dbContactRemark 字段。由于我们并不清楚 userName,而用户的昵称,微信号和我们的备注名都位于 dbContactRemark 列,虽然是 BLOB 格式,但仍然可以通过搜索定位到,例如我搜索女票的用户昵称 jan..。定位到具体联系人以后,我们只需要复制 userName,找到提供 MD5 Hash 加密的工具(我这里使用的是一个在线网址 MD5 Hash Generator),把加密后的字符串复制下来,假设我这里是 mymd5hashedusername

最后,便轮流打开 message_x.sqlite 数据库,找到对应的 Chat_mymd5hashedusername 表,就找到你们所有的聊天记录了。可以先大致浏览一下,如果你们的记录保存完好,回到第一天,看到消息,会不会很开心呢?反正我当时看到是特别开心,很有成就感。

我的微信记录大概占内存 40G,拆分的 message_x.sqlite 也就 4 个,所以我选择手动找表,且每张表是按字母表和数字顺序列出来的,可以很快找到。如果感兴趣的同学还可以通过编程实现。

到此为止我们可以使用 iMazing 将对应的这个库复制到特定文件夹,同时记住我们找到的表 Chat_mymd5hashedusername

在进入下一步分析数据库之前,这里列出来在这个过程中我搜索到的一些资料,其中也包含了 Android 和 PC 版本微信数据库的破解方法。

拿到宝贵的数据以后,这里日历热力图的数据提取就很简单了。可以选择大家偏爱的编程语言实现,只需要以天为单位,统计表中的记录数目即可。下面是我使用 NodeJS 的实现方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
const fs = require("fs");
const db = require("better-sqlite3")("message.sqlite", {
  verbose: console.log,
});
const dayjs = require("dayjs");

const sql =
  "SELECT DATE(CreateTime, 'unixepoch') AS 'date', count(*) as 'count' FROM Chat_mymd5hashedusername GROUP BY DATE(CreateTime, 'unixepoch')";

const stmt = db.prepare(sql);

const jsonArray = [];

let curDate,
  index = 0;

for (const { date, count } of stmt.iterate()) {
  if (index === 0) {
    curDate = dayjs(date);
  }

  // if there are no records one day, set `amout: 0`
  if (index > 0 && !curDate.isSame(date)) {
    jsonArray.push({ amount: 0, date: curDate.format("YYYY-MM-DD") });
    curDate = curDate.add(1, "day");
  }

  index++;
  curDate = curDate.add(1, "day");
  jsonArray.push({ amount: count, date });
}

fs.writeFile("heatmap_data.json", JSON.stringify(jsonArray), (err) => {
  if (err) {
    throw err;
  }
});

基本上使用 sql 语句就实现了,需要注意的是如果某一天没有数据,手动设置为 0。下面是导出的部分数据:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[
  { "amount": 725, "date": "2019-01-26" },
  { "amount": 1024, "date": "2019-01-27" },
  { "amount": 682, "date": "2019-01-28" },
  { "amount": 326, "date": "2019-01-29" },
  { "amount": 252, "date": "2019-01-30" },
  { "amount": 143, "date": "2019-01-31" },
  { "amount": 269, "date": "2019-02-01" },
  { "amount": 259, "date": "2019-02-02" }
]

我这里导出的是数据格式为 json,也可以使用 csv 等其他易于处理的格式。

来到这里,基本上就完成 80% 了,因为热力图已经有很多开源的实现版本,需要的数据格式和我上面使用的也大同小异。我参考了 d3 | reusable heatmap calendar 的实现,修改了部分参数。

当然,在这个过程中我也搜索到了很多优秀的版本,下面都列举出来给大家参考:

得到热力图以后,发挥你的创意,进行一些二次创作吧。由于我没想到什么创意,直接发给了女票让她加工,最终添加了一个大标题。

其实最麻烦的还是拿到微信的聊天记录数据库,有了数据以后,我们还可以创造出很多惊喜,例如词云,词频,或者是不同时段聊天频率分析等等,展现的形式也可以多种多样,都是可以在今后进行探索,送你的她一个惊喜。

希望这篇文章能帮助到你。