huginn的功能扩展性强,可玩度更高一些。

部署huginn

手动部署对系统改动较大,且卸载时也很麻烦,推荐用docker部署

简介

浏览器访问http://ip:3000。登录后如下图所示:

Agents是流水线上完成一道工序的机器人。
Scenarios是完成某项任务的流水线。
Events是某些工序产生的事件,如抓取了某个网页的内容。
Credentials是存储敏感信息(如密码、APIKEY)的地方,这样分享流水线时就不会把密码之类的也暴露了。
Services是查看第三方程序认证的地方,比如想用huginn发微博就必须先将huginn注册为应用并授权。

建立商品价格监控流水线

流水线如下图所示:

需要三个agent

创建网页监控agent

顶部栏Agents——New AgentType选择Website Agent。配置如下图:

Schedule是检测频率。
Sources是上一道工序,由于这是第一道工序所以为空。
Receviers是下一道工序,我这里是编辑所以有选择,重新创建时可留空,等创建下一道工序时选了Sources后这里也会更新。
Scenarios是任务流水线名称,可留空。但任务多时可用来区分不同的Agents方便管理。
Options是重点,用json格式配置工序。Toggle View可用来在图形模式和文本模式中切换,文本模式需要预先escape特殊字符(比如XPath),但图形模式不需要,程序会自动escape。
expected_update_period_in_days是用来判定工序运行状态的,这里的意思是如果2天没有成功更新这个Agent就会被标为红色的Not Working
modeon_change即网页有变动则执行工序。
extract为选择抓取的内容,这里我们取titleprice两项内容。具体如何用浏览器选择可见这节图文教程
注意value那里可以有多种二次处理方式,默认.是输出带标签的原始格式,String(.)则是仅文本。而title这里我们要去掉多余的空格所以用normalize-space(.)price则需要用translate去掉多余的符号仅剩数字方便下一道工序判定是否降价:translate(translate(string(.), '¥',''), ',',''),官方例子中正则和selector是分开使用的,试了下没能结合使用,所以有点臃肿。

创建降价检测agent

新建一个ChangeDetectorAgent。配置如下图:

Sources选前一道工序14TB硬盘价格监控
Optionsproperty需要用到模板语言Liquid的编程

1
2
3
4
5
6
{% assign drop = last_property | minus: price %}
{% if last_property == blank or drop > 0 %}
{{ price | default: last_property }}
{% else %}
{{ last_property }}
{% endif %}

这里是用保存的价格去比较新的价格,如果新的价格低就保存并传入到下一道工序。

创建降价通知agent推送到微信

这里用到的是开源的Bark。装好APP后会得到apikey。
顶部栏Agents——Credentials——New Credential新建名为BARK_KEY的凭据并保存。

新建一个PostAgent。配置如下图:

Sources选前一道工序降价检测。推送angent无需定时,由上一道工序发送的事件自动触发。
post_url按格式填好https://api.day.app/{% credential BARK_KEY %}/{{title | uri_escape}}/{{price | uri_escape}}。这里{% credential BARK_KEY %}会在执行时用你保存的apikey替换掉,而{{title | uri_escape}}会用上一道工序收到的title信息然后用url编码成符合格式的网址。
由于Bark是GET方式,所以payload为空。若是POST方式的推送就把body的内容按格式填入这里即可。
保存。

其他

通过修改.env,增加http_proxy即可让huginn走代理。但只能是全局代理。
Liquid过滤器不支持regex。

调试相关

保存agent前可先点Dry Run调试,看看能否正常输出。
最后一道工序通知后不会生成event,去查看接收设备。
Change Detector Agent调试时要先去Details删掉Memory才好生成新事件,否则要等真降价。
调试时上一道工序不用重跑,将其生成的事件re-emit即可。

参考资料

Agent Configuration Examples
Formatting Events using Liquid
Liquid docs