我写了个工具,能知道我什么时候死

程序当然无法预测一个人什么时候会死,就算人工智能跟各个流派的算命方法结合起来,应该也算不出这个时间。

这个工具只是检测到我死了之后,做一套预设的任务流。

程序怎么判断我死没死

我想了想这个问题,方法有两种

  1. 我在濒临死亡只剩一口气的时候,按下一个按钮,然后任务流自动启动

    DGW2DU6VwAALa7Z

    抛开瞬间死亡这种场景不说,还存在一个矛盾:
    “我在没死之前,即使是濒死阶段,我不知道我还剩一口气还是两口气,万一在还剩三口气的时候按下了这个按钮,那结果不准确,程序设计是失败的”

  2. 每个人每天都会做一些同样的事,假如有一段时间没有做,那是不是可以判断这个人可能去世了

    这里又衍生出两种方案

    • 主动告诉脚本,今天我还活着

      脚本呢一定是跑在服务器上,考虑到能够不限地点,不限设备的告诉脚本我还活着的消息,我最先想到的方案是:访问一个只有我知道地址的路由,只要这个路由今天被访问到了,那就证明我今天活着。

      那么这个路由得是一个没有任何语意的拼写组合,比如说 https://hostname/whwhqiangdongqiang/23333,且需要在 robots.txt 中配置相应的路由规则,不然在我死了之后,脚本在特定的情况下,还会认为我活着。

      纵使一切都按部就班的完成了,仍然会有泄露地址的可能性,于是这个方案显得不是合适,且每天都需要手动访问这个地址,比较麻烦。

    • 脚本自动检测今天的我有没有活动痕迹

      人每天都会重复一些事情,比如:吃饭、上厕所、走路等等

      举个例子:吃了饭就会有垃圾产生,那么垃圾桶的重量就会加重,但是即使在垃圾桶上装上传感器,垃圾是产生了,但是这个垃圾是谁产生的并不能确定。而且,我有可能出去游玩,也有可能没有睡在家里。

      需要找到一种 “跟身份强关联的且每日都会产生的痕迹”,社交网络上的痕迹就很符合这个要求。

获取社交网络上的痕迹

途径有两种:

1. 访问开放平台对应的开发者接口    
2. 爬虫爬取对应的数据

我想了想我每天都会在互联网上留下哪些痕迹,比较常见的有:刷朋友圈、刷头条、刷微博等等等

其中有些很难通过上述的两种方案获取相关信息,比如:朋友圈。

朋友圈比较麻烦是因为:没有网页版也没有可供使用的 api,想要获取评论信息和点赞信息预估得走很多弯路

剩余的信息源中又能分为三种情况:

  1. 需要模拟登录获取记录的,比如头条的阅读记录,模拟登录又有很多途径

    Oauth 登录
    获取登录态登录
    模拟输入账号密码登录

  2. 直接访问对应用户的主页就能获取活动记录的,比如知乎

  3. 提供接口的,比如微博

想要从信息源中知道我死了没有,无非就是从检索一下信息源中最上方的一条信息是否和之前的一致,不一致就说明我还活着。

于是这里又有个问题出现了:

假如我今天没有产生信息,但是我删了一条几年前的信息,那么按照上文的规则,我会被认为已死亡。

规避这种情况有两种方案:

  1. 获取我在这个平台上的所有数据,这样即使删除了一条很久之前的数据,也能被认为是「不一致」,但这方案也会带来一个问题,假如全部数据量十分巨大,脚本就需要完善对应的「反·反爬虫机制」
  2. 从界面中找到能体现「全部数据量」的元素

举个例子

知乎

这是一个用户首页信息
屏幕快照 2017-12-03 上午10.40.37

从中可以看到,我回答了「36个问题」,有「8个想法」,赞助了「18个live」,关注了「1419个问题」
等等等等,将这些数据与首页的信息流结合起来,能规避掉一部分的误判,当然在某些特定的情况下,还是会出现「总量没变,第一条信息流也没变的情况」,可以把信息流的条数适当增大一点,比如十条。这样操作之后,出现误判的几率能降低很多(排除人为欺骗的场景)

如何从页面中获取到对应的信息

从网页调用的接口中获取

屏幕快照 2017-12-03 上午10.29.05
像知乎这样用 React 等框架构建的网页,很多数据是从接口处拿的,找到对应的接口,伪造相关信息后可以拿到接口数据。

从 DOM 中获取

直接从 DOM 中找到对应的数据,这里又会出现一个问题

脚本的 get请求,只是获取到了 HTML 文本,网页中还会有一些 js 代码没有被运行,这意味着浏览器展示的 HTML 和脚本 get请求到的 HTML 是不一致的

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<p id="test">no script</p>
</body>
<script>
window.onload = function () {
document.getElementById('test').innerText = 'hello world'
}
</script>
</html>
</code>

浏览器中的结果:

屏幕快照 2017-12-03 上午11.10.24

脚本获取的结果:

屏幕快照 2017-12-03 上午11.16.50

可以看到,浏览器中对应的 dom节点已经变成了 「Hello World」,而 curl 到的 dom节点还是「no script」

因此,为了让浏览器环境和脚本环境获取到的 HTML 文本保持一致,需要引入一个能解释 js 的工具:「PhantomJS

引入后获取的 HTML:

屏幕快照 2017-12-03 上午11.21.39
可以正常获取到 「Hello World」了

从开放平台处获取对应的信息

微博

在未登录的情况下打开微博的个人主页

屏幕快照 2017-12-03 下午12.01.20

没有登录的状态下获取不到任何数据,从 DOM 中拿数据的路数就行不通了,除非登录。

与其在这里登录,再解析 HTML,不如直接从现成的开放平台调接口。

一顿操作后,获取到了我发出的评论,我发出的微博,我的关注,我的收藏信息。

最后

我写了三个信息源:「知乎」、「豆瓣」、「微博」,
屏幕快照 2017-12-03 下午12.15.35
将检测时间调整(默认为一天)为 6分钟测试一下,6分钟内没更新这三个信息源,我就死了。然后脚本自动执行一段任务流,比如在我的博客发一篇预先设置好的博文,将我的密码文件发给指定邮箱等等等等。

像 hexo 这类的博客程序只需要进入对应的目录,执行 hexo clean && hexo g 就能发博客,流程还是比较简单的。

代码逻辑倒转一下,这也能成为一个特别关注的工具,当特别关注的人「发布了一个新回答的时候」/「看了本新书的时候」,能通知到自己。

缺点

这玩意缺点仍然很明显,昏迷状态和被限制人身自由状态也会被误认为死亡。

而且无法保证微博不更换接口,也无法保证豆瓣和知乎的 DOM 结构永远不改。

项目地址