“silver iMac on brown wooden desk” by Roman Bozhko on Unsplash

自动化工具 Huginn 入门指南

日向
日向
Jan 18, 2018 · 12 min read

Huginn 是一个类似 IFTTT 的工具,可以按照要求自动完成任务,如监视状态更新、获取网页内容、设置条件触发等。具体的介绍可以看 这里

我们有时候可能会想监视一个网站的更新,例如字幕组更新或是学校教务系统通知,有的网站可能会有 RSS、官方微博等提醒更新的渠道,但如果没有,或是我们想要更迅速地,更清晰地,按照自己的要求输出更新条目的话,我们就可以用上 Huginn 这款工具了。它能够抓取网页、按指定的格式输出更新、去重、筛选、推送到 Telegram 或 Slack 等,配合其他 Agents 和 Scenarios 还能实现更多的自动化任务。

安装 Huginn

安装这些工具总是一件麻烦的事,但有了 Docker,就可以省下很多事,不必再跟配置环境时的各种出错打交道。这次我使用 Docker 安装 Huginn。

P.S. 使用基于 Docker 的服务器管理应用 — — HyperApp 来安装更加便捷,可以参照 此处 完成。

首先要在服务器上安装 Docker,安装方法请见 此处

Huginn 的使用依赖 MySQL 数据库,可以接入 MySQL 的 Docker 容器,也可以使用 Huginn 镜像的内置数据库。使用独立的 MySQL 容器的话有利于在主机内共享 MySQL 服务,不必启动多个 MySQL 占用资源。

接入 MySQL 容器首先需要有一个 MySQL 容器:

docker run -d --name mysql \
-e MYSQL_DATABASE=数据库名 \
-e MYSQL_USER=数据库用户名 \
-e MYSQL_PASSWORD=数据库密码 \
-e MYSQL_ROOT_PASSWORD=数据库Root密码 \
-v /data/mysql:/var/lib/mysql \
mysql:5.7

Huginn 似乎不兼容更高版本号的 MySQL,所以这里选用的是 5.7 版本。数据库会被备份至服务器里的 目录里。

然后安装并启动 Huginn:

docker run -d --name huginn \
--link mysql:mysql \
-p 3000:3000 \
-e HUGINN_DATABASE_NAME=数据库名 \
-e HUGINN_DATABASE_USERNAME=数据库用户名 \
-e HUGINN_DATABASE_PASSWORD=数据库密码 \
-e TIMEZONE="Beijing" \
huginn/huginn

上面还配置了时区,其他的环境配置项可在 此处 查阅。稍等几分钟之后访问 ,即可看见登录界面。登录名 ,密码 ,登入后可更改密码。

也可以使用内置数据库,省去单独安装 MySQL。建议挂载一个目录来备份内置数据库,如下例将备份至 路径:

docker run -d --name huginn -p 3000:3000 -v /data/mysql:/var/lib/mysql -e TIMEZONE="Beijing" huginn/huginn

使用方法

在 Huginn 里有几个概念:Agents 是执行任务的一个个环节,它们分别是不同的功能,完成一项任务中的一环。我们需要通过配置 Agents,排列 Agents 来完成一项任务。

Events 是每个 Agent 之间传递的信息,例如网页抓取 Agent 抓出来的更新就会成为一个 Event,传送给下一个 Agent 例如格式化 Agent,通过对网页内容的格式化输出一个 Event,再传送给 Telegram Agent,就能完成一项抓取网页更新后推送给 Telegram 的任务。

Scenarios 是 Agents 的集合,我们自己可以选择 Agents 添加成为一个 Scenario,一般一个 Scenario 是完成一项任务的 Agents 的集合。通过对 Scenario 的管理实现对 Agents 的分组批量管理。

Credentials 里面可以保存常量,在 Agents 中调用的时候使用 即可调出保存的

常用 Agents

登陆后点击顶部导航栏的  — ,即可开始新建 Agent。不同的 Agent 配置也不同,对 Agent 和其配置项的介绍在配置页面的右边栏里有详细说明。

指定该 Agent 的自动执行频率,一般一系列 Agents 里只需要指定第一个 Agent 的 Schedule,后面的 Agent 就能跟着动了。也可以不设定 Schedule,利用另一个 来控制自启动。

是控制这个 Agent 的启动、执行、停用等的另一个 Agent,一般不用填,当你配置了另一个 Agent 时会自动填上的。

指定 Event 的保存时长,对于网页抓取 Agent 的话保存的 Events 可以帮助它检测网页是否更新。如果后面会配置去重 Agent 的话这里就不必设置很长的时间。

是上一个 Agent,也就是会把 Event 传过来的 Agent。 则是下一个 Agent,即本 Agent 所产生的 Event 的接受者。在还没有建立别的 Agent 的时候这两项都可以留空,以后会自动填上的。

勾上的话,在 Event 传入后会即时执行 Agent。否则 Event 传入后要等上一点时间再和其他 Agent 凑一起执行。开启这个选项会使资源占用增加,对于去重 Agent 建议不要开启,作者说这样会有 Bug。

解析网页:Website Agent

里进行配置,配置项的写法需要遵循 JSON 语法。

里填入要抓取的网页,一般是最新文章的页面。把 改成 可以填入传入的 Event 内的项目,如

里填 则只输出更新的条目, 会输出所有条目, 则会跟传入的 Event 合并。 指定文档类型,分别是 或者 ,不同类型抓取写法不一样,示例可以看配置页面右边栏。

接下来以某个网页为例子,示例如何对网页的结构进行分析。打开要监视的网页,可以看到一个文章列表。现在要做的就是发现文章列表内每条链接的结构,并使用 XPath 语法表达出来。

右击文章列表内的链接,,发现每个 外面都包裹着一个 ,虽然看起来很有规律,但是我还没找到这样的规律要怎么用 XPath 表达出来。

所以要换一条路走,再观察一下,发现所有链接其实都在 里面,有这个唯一的 就好办了。我可以让 Website Agent 寻找这个页面内 里面的 里面的所有 。写成 XPath 就会像这样:

//td[@class='substance_r']//li/a
  • 表示选取拥有 属性的
  • 指选取所有匹配的,不管是不是根元素;
  • 指选取该 下的所有 ,不管 是不是根元素;
  • 表示选取该 下的 ,并且两者之间没有其他元素包裹。

回到新建 Agent 的页面,点击 旁边的 ,在 下的 里,把 改成 ,填上刚才写好的路径,用 指出网址在 里。

同理,在下面的 中,由于文章链接的标题和地址都在同一个 里,所以直接用上面的路径,但是 的值 要改成

然后把原本模板里的 修改为 ,以获取文章更新时间。回到网页里,看到更新时间是在与 同级的 里,所以把 XPath 路径里的 修改成 。但是网页里的时间是显示成 的样子,需要把它转为 的形式。这里可以用到 XPath 字符串函数 中的 ,可以把字符串 中的 替换成

P.S. 其实在 里还可以写成 CSS 选择器的形式,并不强制使用 XPath。

完成之后可以点击 看看效果,满意就点击 保存。

格式化输出:Event Formatting Agent

从网页 Agent 里生成的 Agent 一般都是 JSON,要格式化的话就要用到这个 Agent。在 里进行配置。

会把新生成的 JSON 和旧 Event 合并成为新 Event,选 则不合并。

里描述如何格式化。支持 Liquid 模板语言,具体用法请点 此处

我常用的有:,格式化日期; ,输出一个换行; ,正则替换; ,删掉匹配内容; ,输出当前时间。

判断过滤:Trigger Agent

可以对 Event 里的某一项进行判断,结果为假则被过滤不会进入下一个 Agent。

里填被判断的项目,如 为真则保留传入的 Event 内容; 里可以填入 Liquid 表达式,可以一并被输出到新 Event 里。

可以是 ;在 里填正则式,或用来对比的数值,或者 的范围。

去重:De Duplication Agent

可以存储一段时间的 Event,当新 Event 进入时判断与旧 Event 有无重复,重复则不输出。对这个 Agent 的 可以设置得稍长。

Options 里的 指定要去重的旧 Event 里的哪一项,一般会是 指定要对多久前的 Events 进行比对,设定为 则对存储的所有 Events 进行比对。

生成 RSS:Data Output Agent

里选择一个 Agent 作为 Event 的来源,如上面的网页 Agent。在 里填写:

{
"secrets": [
"a-secret-key"
],
"expected_receive_period_in_days": 2,
"template": {
"title": "通知公告 - 本科生院",
"description": "通知公告 - 本科生院",
"link": "http://uc.edu.cn/tzgg.htm",
"item": {
"title": "{{title}}",
"link": "http://uc.edu.cn/{{url}}",
"pubDate": "{{date}}"
}
},
"ns_media": "true"
}

默认的模板里没有 ,所以要自己增加。如果获得的 里面没有网站的域名,在这里的 之前可以把域名加进去。

保存好以后,当上游 Agent 推送 Event 到这里,点击 Agent 列表里这个 Agent 的名字,就可以看到输出的两个链接了。

复制 的链接,直接添加到 RSS 阅读器里,或是托管到 FeedBurner 后添加进 RSS 阅读器里,就获取到这个网站的更新了。

Telegram 推送:Telegram Agent

使用此 Agent,可以将接收到的 Event 通过 Bot 发送到某个频道、群组或个人。Agent 会把传入的 Event 的 里的内容发送出去,建议上游建立一个格式化 Agent 以控制推送信息的格式。

使用前需要申请一个 Telegram Bot,申请方法可以参考 此处。配置好 Options 就可以用了。

自动执行:Scheduler Agent

通过 Cron 表达式编排时间表,自动对某个 Agent 执行启用、禁用、运行操作。 里选择被控制的 Agent。 指定操作, 里写时间表。

参考资料

让所有网页变成 RSS — — Huginn

Every Little Thing

生活琐事、游记、影评、吐槽与笔记

日向

Written by

日向

Nothing lasts forever.

Every Little Thing

生活琐事、游记、影评、吐槽与笔记

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade