【177】30周 用 Mercury API 改善 iOS 的网页剪藏

Platycodon
03月21日

用 Mercury API 改善 iOS 的网页剪藏

| 本文为付费栏目文章,您已订阅,可阅读全文 |

iOS 网页剪藏的现状

iOS 天生是适合内容消费的平台,而网页阅读是内容消费的重要形式。因此,iOS 上的网页剪藏是一项刚需。与桌面平台上有各种浏览器插件和保存方式可供选择不同,在限制较多的 iOS 平台上,剪藏需求的实现主要依赖于第三方 app 提供的分享插件(Share Extension)。例如,Evernote 和 DEVONthink 都提供了这样的插件,在浏览网页时通过分享菜单调用,就能将网页内容导入相应的 app 中。


Evernote 和 DEVONthink 的分享插件

然而,这种解决方案是很不完美的。例如,分享菜单只在用 Safari(或第三方 app 调用的 Safari View Controller)浏览网页时能有效导出网页内容。在其他场合,分享菜单传出信息的往往只是一个 URL,插件必须对该地址发起访问才能获取网页内容。但受限于 iOS 对分享插件在资源分配上的严格限制,这一过程往往非常缓慢且容易失败。即使能成功抓取,最终获取的也往往是较为简陋的移动版网页。如果原始网页上的动态元素较多,那么抓取结果就会更加「惨不忍睹」了。
如何改进这些不足呢?可以看到,上述问题都是 iOS 系统的限制造成的。如果能把获取网页内容的任务从本地转移到远程,就能绕过这些限制,获取更好的网页抓取结果。
Web API 正是能满足上述需求的工具。关于 Web API 的概念和用法,少数派此前的文章(其一其二)已经有较为系统的阐述,在此不赘。概括而言,API 可以被理解成一个「黑盒」,接纳特定类型和格式的输入,然后返回一定的结果。例如,对于实现网页文章剪藏需求的 API 来说,其输入内容就应是原始网页的 URL,而输出内容则是抓取的文章。在 iOS 平台上,Workflow app 提供了对 Web API 的完整支持,再结合其分享插件,就能实现良好的文章抓取效果。


原始网页、Evernote 的抓取结果和 Mercury 的抓取结果

至于 API 的选择,目前在抓取文章方面最完善的当属 Mercury。如果你是 RSS 的重度用户,应当对这个名字并不陌生——包括 Reeder、Unread、Fiery Feed 在内的众多 RSS 客户端都是通过调用 Mercury API 实现「抓取 RSS 全文」功能的。下文也将以其为例进行演示。

基本使用

Mercury 的使用是免费无限制的,但要求注册账号从而获取 API Key。


注册 Mercury 并获取 API Key

本文准备了一个 workflow 来演示 Mercury 的功能。请首先 下载 该 workflow,将自己的 API Key 填入标示的空格中。


填入从 Mercury 申请的 API Key

然后,用 Safari 打开任意一篇在线文章,通过分享菜单传给该 workflow(或者也可以在其他 app 中长按链接,然后分享给该 workflow)。


示例 workflow 的核心步骤——访问 API

稍等片刻,即可在弹出的预览窗口中看到 Mercury 抓取的文章。该 workflow 默认以 Evernote 作为保存的目的地,你可以根据需求将该步骤换为其他偏好的保存位置。

进阶应用

上文所用的 workflow 只是 Mercury 的最小配置,但该 API 所返回的响应内容并不只有文章正文,还包括很多有用的信息,可以用来实现其他各种需求,例如获取文章摘要、还原短链接真实地址、估测阅读时间等等。下文将首先用两个例子说明如何进一步利用 Mercury 的功能,然后介绍 Mercury API 响应的结构,你可以据此定制满足自己需求的 workflow。

例一:自定义样式

很多用户不喜欢在 Evernote 等工具中做阅读和批注的,原因就在于其默认的笔记格式是比较简陋的,既不美观也不易读。而如果改用 Mercury API 抓取文章,由于其输出格式是 html 文本,完全可以用对待其他 html 源文件的方法对其进行修改,以改变最终呈现结果的外观。
上文提供的演示 workflow 中已经嵌入了自定义样式,但该部分代码暂时被注释掉了。将下图所示步骤中的标红部分删去,然后再次运行该 workflow。


编辑 workflow 以启用自定义样式

可以看到,文本的大小、行距、行宽、字体等都有了改变,整体阅读效果有较大改善(为正确显示其中的中文字体,你需要按照此文方法在 iOS 上安装额外字体)。


自定义样式后的抓取结果

你可以自行修改这部分代码来实现偏好的文本样式。

例二:与任务管理工具的整合

网页剪藏和任务管理是两项相关的需求——一个新收集的网页往往也意味着一个新的待办事项。虽然大多数任务管理工具都提供 iOS 分享插件,支持将链接创建为新任务,但其在实际使用中也存在与 Evernote 等插件类似的问题:难以正确抓取网页标题、不能将短链接和附加了跳转参数的冗长链接自动还原等。
Mercury API 为解决上述问题提供了一种途径。其响应中含有真实链接、文章摘要等数据,只要通过 Workflow 将这些信息填入新建待办事项的动作中,就能很好地改善所创建任务的准确性和直观性。
下面以 Todoist 为例简单进行一个演示,其他任务管理工具可以参照适用。首先 下载 这个 workflow,可以看到,其主要工作是从 Mercury 返回的结果中提取 urltitleexcerpt 等键值,并填入新建任务的动作中。


调用 Mercury API 返回信息添加任务

然后,同样通过分享菜单给其传递一个链接并观察运行结果。相比于通过 Todoist 分享插件直接保存的任务,此处使用的方法不仅创建了含有正确超链接和标题的任务,还将网页摘要作为备注填入其中,事后回顾显然更加直观。


不同方式添加任务的结果对比

Mercury API 响应的结构

Mercury 的响应是 json 格式的,但遗憾的是没有任何官方文档,网站上只提供了一个非常简陋的使用示例。我猜想,或许是开发者认为这个 API 的功能足够简单,根本不需要过多解释。但实际使用中,Mercury 返回结果中一些内容的作用并不一目了然,甚至根本没有在官方示例中出现,因此仍然需要说明。下表是我经过试验后的总结:


Mercury 响应中的键及其含义(非官方)

一些值得说明的键:
  • content:抓取的 html 格式正文,最外层是一对 div 标签,里面以 article 标签表明文章身份。
  • dek:文章小标题(dek 是新闻出版中的黑话,来源于 deck,指位于新闻正题与正文间提纲挈领的副题),一般会从原网页的 description 等标签中抓取,如果抓不到就留空,用处很小,基本可被 excerpt 键替代。
  • url:原文链接,注意其并非调用 API 时输入链接的简单重复:如果传入的网页链接是短链接(如 bit.ly/wxyz),那么会被还原为真实链接;如果传入的链接带有跳转参数(如 ?utm_medium=website),那么这些尾巴会被去掉。
  • excerpt:文章摘要,和 dek 一样会从原网页的 description 等标签中抓取,但如果抓不到会从原文首部截取几个单词作为键值。

替代方案

尽管 Mercury 的性能在大多数时候都能满足需求,但也不可能做到十全十美。因此,找一个备用选择也是有必要的。boilerpipe 就是一个功能类似的免费 API。与 Mercury 相比,其优势在于不需要注册和鉴权,自定义参数较多,支持多种抓取方式和输出格式,用起来更加灵活。例如,对于一些并不包含明显文章内容的网页,Mercury 很难抓到有效信息,而 boilerpipe 就可以通过改变抓取方式,尽可能从中获取主体信息。不过,其劣势则是抓取结果经常不如 Mercury 干净、不支持抓取分页文章等,读者可以根据自己的不同需求进行选择。
你可以 下载这个 workflow 来测试 boilerpipe 的效果。


用 boilerpipe 从 Dropbox 的介绍页面抓取主体信息

boilerpipe 在使用上与 Mercury 完全类似,在此只列出部分常用参数供参考。唯一需要注意的是该 API 默认直接返回 html 格式结果,并且保留原网页上所有内容,只是将文章部分标为高亮。因此,如果是用作文章剪藏,一定要在请求中将 output 参数设为 htmlFragment
  • API 接口地址:http://boilerpipe-web.appspot.com/extract
  • 必选参数
    • url:链接地址
  • 可选参数
    • extractor:抓取方式
      • ArticleExtractor:缺省值,抓取网页文章
      • DefaultExtractor:比 ArticleExtractor 更宽松,但一般不够准确,备选
      • LargestContentExtractor:抓取网页中内容最多的板块,适用于不包含明显文章内容的网页
      • KeepEverythingExtractor:不过滤内容,将网页内容全部输出
    • output:输出方式,可选值为 html(缺省值,见上文说明)、htmlFragment(只输出文章部分,建议选择)、jsontextdebug(仅排错用)。

上一期
第 30 周预告:「大数据杀熟」你怎么看?
下一期
用辅助功能键盘自定义一个工具栏
 
精选评论(2) 我的评论