1 引言

我有时总会觉得自己是个「奇葩」: 在现在各种算法推荐大行其道的当下,我却偏偏不喜欢算法推荐,因为这种「千人千面」的模式,总让我担心自己会陷入「信息茧房」的焦虑之中,此外我也希望可以看到一些我兴趣之外的内容。

我算是很多年的 Twitter 老用户了,使用 Twitter 已经超过十年了,只是在马斯克收购 Twitter,新增了一个 “For You” 的推荐流之后,越来越没有兴趣看,不是吵架就是借极端观点/话题引流。

于是,我转向了Telegram频道,并为此打造了一个专属的「挖掘好帖」工具。

在最近的一年时间,我订阅了越来越多的 Telegram 频道,频道主可以向所有的订阅者广播内容,因为 Telegram 频道都是由频道主发布的,这给了我一种主动发现、主动阅读,而非被动接受算法推荐的感觉。

有频道主分享 twitter 上的内容时,也可以算是某种意义的「编辑精选」了。

当我订阅越来越多的频道之后,发现有些频道主太能聊了,一天能发几十个帖子,有些只是碎碎念,有些却是思考和精华。

所以我就在想,是否有个好用的挖宝藏(挖坟)工具,可以把频道的热贴,精华帖都列出来呢?

2 灵感

另外一个我高频使用的网站就是 Reddit, 不了解的 Reddit 的朋友可以理解成它是网站的百度贴吧,可以有不同的子版(subreddit),相当于不同的吧, 然后每个子版都有一个 top 的功能,可以按照过去一小时,过去24小时,过去一周,过去一年,历史全时段按帖子的顶贴数进行排序。

类似 rust 这个子版的历史精华帖:https://old.reddit.com/r/rust/top/

那么,我是否也可以对 Telegram 频道也实现类似的功能呢?

我可以把某个频道所有的帖子都爬下来,然后按点赞数,转发数,点击数按不同的时间段进行排序,

支持不同的时间段:包括一周内,一个月内,一年内,和历史所有帖子

相当于根据频道的订阅者的用手投票,挑选出不同时段最精华的帖子

3 技术挑战

仔细分析之后,我发现检索频道并构建热榜是个相当有趣的技术问题,也与频道帖子本身的产品属性有关。

在我爬取某个频道的所有帖子后,如何与频道的最新动态保持同步更新呢?

毕竟像阅读数,转发数这些数据也是一直会更新的。

但是大部分历史的帖子的阅读数据都是不怎么会变化的,比如半年前的帖子可能就不会有人去翻看,订阅者大多只会关注最新的帖子。

每次都所有帖子都重新爬取一次固然可行,但是效率太低,毕竟绝大部分的帖子的数据都是不怎么变动的,怎么平衡性能与数据的及时性呢?

有点像超简化版本的搜索引擎问题了。

查询的时候要支持不同的时间段,按不同的指标进行排序,如何保证查询的性能呢?

总不能每次查询都重新计算一次吧,这样在帖子非常多的热点频道,就会出现查询的性能瓶颈。

4 解决方案

在仔细考量,权衡利弊之后,我取了个折衷的方案:

  1. 第一次爬取某个频道时,全量爬取并索引
  2. 每天定时重新爬取最近30天的帖子数据,作增量更新
  3. 每周再爬取和索引一次全量数据

就这样兼顾性能,成本以及数据及时性,又不会造成过多的重复爬取。

而对于查询性能,我选择了建立物化视图(material view)的策略, 每次爬取成功之后就重新计算,更新一下 material view, 耗时可能比较长,每个频道更新视图大概需要个十几秒。

但此后所有的查询都直接指向这个预计算好的视图,数据库还可以利用缓存优化,以空间换时间,查询性能因此得到保障

5 使用示例

使用方法非常简单:

  1. 点击链接打开机器人:https://t.me/tele_ranker_bot
  2. 在对话框中输入 /rank <频道链接> ,例如 /rank https://t.me/pipeapplebun
  3. 首次检索一个频道时,机器人需要一些时间来建立索引(如下图所示),完成后会通知用户:

完成之后就会发消息通知用户

然后用户就可以按照点赞数,转发数,点击数查看帖子

通过这个工具,我甚至发现了一些有趣的现象:

某些频道看似有十几万订阅者,但近期帖子的点击数仅有一千多,还不到百分之一,数据真实性令人存疑。

6 结语

有了这个频道检索工具,我终于能在一个频道里高效「挖坟」了,再也不用担心错过沉淀在时间线里的精华。

不管是想回顾精华,还是挖掘隐藏好帖,甚至是做简单的数据挖掘,这个机器人都能搞定,举个例子:

  • 找最近一个月点赞最多的帖子
  • 看看历史上点击最高的内容有哪些

这次,我总算为自己、也为可能有同样需求的你们,打造了一个称手的工具。

推荐阅读

qrcode_gh_e06d750e626f_1.jpg 公号同步更新,欢迎关注👻