在很早以前小站中有一个留言板功能,存储了所有留过言访客的 Gravatar 头像,然后我把他们组成了一个照片墙,并中二的称之为叹息之墙。但是随着空间到期和域名没续费这个墙就坍塌了,虽然当时的代码还在,但是数据已经难以回溯,现在想想不免有些遗憾。
于是我就在想,如何能找到一些有关系的头像重新组成新的叹息之墙呢,微信好友头像应该是目前能利用的最好素材了。
我抱着伸手党的态度试着搜了下获取微信好友头像 - Google 搜索,发现大部分的方案都过期了,而且微信好像已经不再提供网页版,登录网页版就会出现以下提示:
为了保障你的账号安全,暂不支持使用网页版微信。你可以前往微信官网 https://weixin.qq.com/ 下载客户端登录。
这就有点麻烦了
可是在墙里墙外徘徊穿梭这么多年的我是相信第一性原理的,方法论就是用来解决没有解决过的问题而存在的。
首先是如何获取好友头像的 url 地址
最直接的方式就是抓包,包括微信网页版实际最本质的基础也是抓包获取头像 url。
这里我使用了 Quantumult X 作为我的抓包工具(其他工具类似)。
众所周知微信的缓存是很重的,微信通讯录里缓存过的头像不会再重新请求,设置里清缓存也清不掉,那么这就只剩下两条路,一条是本机删了之后重装,但是这样会丢失所有的聊天记录;另一条是找个旧手机重新下载微信登录账号。一比较,那自然是旧手机方案影响更小。
安装微信、登录微信、抓包微信通讯录,很快啊,一套数据就抓好了,然后导出抓包的文件,隔空投送传送到电脑上(下图是 Quantumult X 抓包后导出的格式)。
然后就到了解析抓包的数据并下载图片到本地的环节
分析了下抓包导出的文件格式,要想获得所有图片的下载地址,则需要获取所有文件夹下 basic 的内容,然后组成一个数组队列,以方便批量下载。
因为网上的教程绝大部分都是 Python 的,虽然 Python 很强大,但是我用起来没有那么顺手,而且文件处理这种简单的功能用 Node.js 会更容易些。
这里直接上相关代码了,思路很简单,就是组装数组+下载头像图片到指定目录。因为功能简单,甚至连 npm install
都不需要。
头像我下载的是缩略图,如果需要下载原图,需要把 /132?tp=wxpic
改成 /0
代码换个环境不一定能百分百运行,可以根据实际情况调试修改,也没几行。
const fs = require('fs');
const path = require('path');
const http = require('https');
let files = {};
let fileNames = [];
function readBasicFiles(dir) {
fs.readdirSync(dir).forEach(file => {
let filename = path.join(dir, file);
let stat = fs.lsatSync(filename);
// console.log(filename);
if (stat.isDirectory()) {
readBasicFiles(filename);
} else if (file.endsWith('basic')) {
let content = fs.readFileSync(filename, 'utf8');
if (content.includes('wx.qlogo.cn')) {
fileNames.push(content.replace("?tp=wxpic", ""))
}
}
});
}
readBasicFiles('/Users/apple/Downloads/2023-10-07-133014');
function download(url, filePath) {
return new Promise((resolve, reject) => {
const request = http.get(url, response => {
const stream = fs.createWriteStream(filePath);
response.pipe(stream);
stream.on('finish', () => {
stream.close();
resolve();
});
});
request.on('error', err => {
fs.unlink(filePath, () => {
reject(err);
});
});
});
}
async function main() {
for (let url of fileNames) {
const fileName = url.split('/')[5];
await download(url, `downloads/${fileName}.jpg`);
console.log(`Downloaded ${fileName}`);
}
}
main();
喝几口茶的功夫,头像就下载好了。
573 个朋友下载了 572 张头像,正确率高达 99.8%
拼接成「叹息之墙」
这是最后一步了,之前的实现方式是写的 html,还做了一些 CSS 特效,这次我懒逼了,直接选择用工具生成。
这里使用了 Free Photo Grid & Collage Maker for Mac OS X & Windows - CollageIt,感谢强大的 Google 让我快速找到了它。
现在看起来就有模有样了,基本满足了我的需求。
至此,需求完结。
本文的代码和方案都是通过家里 2012 年的 MacBook Pro 产出,感谢 MD101 这么多年的陪伴和付出。