Hugo 生成的 RSS 不能被识别

2018/07/20

这件事情折腾我两天了: 我使用 Hugo 生成的 RSS feed 文件 (.xml) 无法被一些阅读器识别 (比如 macOS 的 Reeder), Inoreader 网页版可以识别, 但部分文章抓取不全. 然而 JSON 格式的 feed 就没有这种问题.

对比用 Hugo 生成的问题文件和一些能被正常抓取的 RSS 文件, 发现它们在结构上并没有太大差异. 而在排错过程中我还观察到了了很关键的一点: 若 RSS 设置成只输出摘要, 就不会出现这种问题.

所以问题肯定是出在文章的内容上了.

我先把 RSS 的输出条目数改为 1, 然后新建了一个 MarkDown 文件 (这样 RSS 中就只包括该文件所对应的条目), 随便输点内容, 重新生成站点. 发现此时的 RSS 是可索引的, 这就进一步证实了我上面的猜想.

接着逐渐增大输出条目, 当条目到达 5 时, 问题复现, 那么就可以开始着重调查条目 5 对应的源文件 item5.md.

打开 item5.md, 删除正文内容, 如我所预料的, 此时生成的 RSS 也可被索引. 接着每次只保留文章的一段, 重复上述步骤. 最后把范围缩小到其中的一段: 只要存在这一段, 生成的 RSS 文件就是不正常的. 然而仔细观察后也没找到什么不寻常的地方. 再用 Vim 打开来看, 终于发现猫腻, 这一大段文字中, 插入了几个奇怪的, 诸如 "^H"、"^[" 的字符, 而刚才在 VSCode 中则完全没有显现出来. 尝试把这些字符删掉, 然后… bingo! 生成的 RSS 文件正常了😆.

至于为什么文章内容中包含控制字符 (比如 "^H"), 会影响生成的 RSS feed 的 抓取, 是因为 XML 1.0 (RSS 协议所规定的 feed 格式) 中不允许有控制字符, 详情可以看这里. 既然生成的 XML 文件无效, 当然也就无法被正确识别了.

再提几点:

  1. 这次教训之后, 我果断打开了 VSCode 显示控制字符的功能 (事后才发现有这功能)
  2. 可以用一些命令来查找文件中是否含有控制字符, 如 grep '[[:cntrl:]]' file
  3. 我还是很佩服自己的, 在什么思路都没有的情况下, 硬是死磕着把问题解决了

最后我还是有两个疑惑: