☰
TT-RSS无法导入RSSHub源?五大根因排查与修复实战
2026/10/10 6:58:46 网站建设 项目流程

用了这么多年 Tiny Tiny RSS(TT-RSS),再加上自建的 RSSHub,我一直觉得这是目前最舒服的一套订阅组合:TT-RSS 负责把散落的消息源收拢到一个界面里,RSSHub 负责把那些没有 RSS 的网站“变”出 RSS 来。尤其是现在很多站点都不再做 Feed 输出,自建 RSSHub 几乎是刚需。可就在这种刚需场景下,很多人会碰到一个特别憋屈的问题——明明浏览器里打开 RSSHub 的链接,XML 格式的 Feed 一切都正常,但一贴进 TT-RSS 的“订阅源”框里,要么提示找不到源,要么一直卡在“更新失败”,甚至直接显示“错误 404”。

这问题我前前后后踩了不知道多少坑,今天就把排查思路和修复方法完整写出来。我会先解释这条订阅链路到底断在哪一个环节,再针对最常见的几类故障给出可复现的验证方法和解决方案,最后附一个进阶案例:用 TT-RSS + RSSHub 去追踪特定作者的文献更新。

1. 先把问题圈出来:到底是卡在哪一步

1.1 一条 RSS 订阅走过的完整链路

TT-RSS 订阅任何源,表面上只是“输入 URL、点保存”,但底层其实要完成一整条数据链路。你输入的地址会先被 TT-RSS 服务端请求,拿到 Feed 内容后再解析,然后入库,最后你刷新页面才能看到新文章。这条链路大致可以切成四段:

  1. RSSHub 服务本身能不能正常工作,也就是你自建的实例是否真的在对外提供 XML。
  2. TT-RSS 所在的那台服务器,能不能通过网络访问到 RSSHub 地址。
  3. TT-RSS 的抓取程序能不能顺利把请求发出去,并且在超时时间内拿到完整响应。
  4. 拿回来的内容,TT-RSS 有没有正确识别成它认识的 RSS 格式。

绝大多数“无法导入”的问题,原因都不在 TT-RSS 本身,而是前两段就挂了。我用这个模型排查过很多次,基本能筛掉八成问题。

1.2 先确认报错:不是所有失败都是“无法导入”

遇到问题第一步是看清楚 TT-RSS 给出的报错信息,不同报错背后完全是不同方向的排查思路。常见的提示有这么几类:

  • 错误 404:TT-RSS 请求了这个地址,但服务器回了个 404。说明网络通,问题出在 URL 路径或者路由参数。
  • 错误 0或者cURL error 28:请求超时。说明 TT-RSS 有可能发出去了,但对方迟迟不响应,或者在响应前连接就被掐断。
  • 未找到源/无法解析:TT-RSS 拿到了响应,但内容不是它认为的 XML Feed,或者 XML 结构不标准。
  • 429 Too Many Requests:更新太频繁被限流了,常见于 RSSHub 官方实例,自建实例也可能发生。
  • 什么都不报,但文章数永远是 0:源被“识别”成功,但抓不到新内容,这种往往是路由参数没对上,返回的是一个空 Feed。

我在排错时会把报错截图存下来,因为后面开调试模式、看日志时,需要拿这些关键信息去对照。

1.3 用“对照组”快速确认 TT-RSS 本身没坏

TT-RSS 本身没坏这个前提很多人忽略。如果你往同一个 TT-RSS 里填一个已知正常的源,比如某个大型科技博客的官方 RSS,能正常抓取,那么 TT-RSS 服务端、数据库、抓取定时任务基本没问题。问题就锁定在“RSSHub 自建源”这一侧。反过来,如果对照组也失败,就得先检查 TT-RSS 所在服务器的网络、PHP 配置和定时任务状态。

这个对照组不需要很复杂,我一般用这个地址测试:

curl -I https://hnrss.org/newest

能返回 200,说明至少外网是畅通的。

2. 五大常见根因,逐一排查

2.1 地址与路由:最容易被忽略的“拼写陷阱”

RSSHub 的路由对大小写、路径格式、参数分隔符都很敏感。同一个作者名,大小写不同可能就返回空。中文参数如果没做 URL 编码,TT-RSS 拿到的可能是一个残缺地址。举个例子,一个正常的路由长这样:

https://你的域名/arxiv/query/au:Zhang_San/1

但如果你手抖写成了:

https://你的域名/arxiv/query/au:zhang+san

RSSHub 返回的确实还是 XML,但可能是空 Feed。更麻烦的是,有些带中文的查询参数必须编码,浏览器会自动编码,但你复制到 TT-RSS 时编码可能丢了一半。

我的建议是:先用 RSSHub 自带的调试页面或者直接用 curl 在命令行里把地址验证一次,确保参数完整。再把地址粘贴到最小化测试环境里,排除“手滑”造成的字符污染。

2.2 RSSHub 服务本身没吐出来

自建 RSSHub 最常见的死法是“服务死了但你以为它还活着”。由于 RSSHub 部署多用 Docker,容器不会在你 SSH 时给你弹提示,镜像还在跑、端口还在听,不代表路由真的能出数据。RSSHub 的很多路由依赖上游网站,比如某期刊官网临时改版、某平台加了验证码,都会导致路由返回 503 或者干脆 5 分钟超时。

这时不要在 TT-RSS 里反复点“更新源”,而是在 RSSHub 服务器本机直接请求该路由:

curl -L "http://127.0.0.1:1200/你的路由"

注意加-w "\n%{http_code}\n"看一眼 HTTP 状态码。如果本机都返回 5xx,说明是 RSSHub 依赖的上游出了问题,和 TT-RSS 一点关系都没有。这种情况只能等或者换参数试试。

2.3 TT-RSS 服务器能不能真正访问到 RSSHub

网络层面的坑通常分为两类:一类是 TT-RSS 服务器与 RSSHub 服务器之间的隔离,另一类是 DNS 和 IPv6 解析问题。

如果你把 RSSHub 和 TT-RSS 部署在同一台机器上,就可能遇到一个经典的“本机访问本机”问题:TT-RSS 请求 RSSHub 的域名时,DNS 解析到公网 IP,然后机房防火墙或者安全组把这个回环流量挡了。最简单的验证方法是直接使用127.0.0.1或localhost作为 RSSHub 地址。如果这样能通,说明就是公网 IP 访问受限。不过用 localhost 之前要确认 TT-RSS 配置里没有禁用这类地址。

还有一个很隐蔽的点:有些服务器默认解析出的 IPv6 地址连不通,TT-RSS 的 curl 会尝试 IPv6 然后白白等上好几秒。在服务器上执行:

curl -6 -I https://你的RSSHub域名 curl -4 -I https://你的RSSHub域名

如果-4正常而-6超时,你就要去 TT-RSS 的配置文件里强制走 IPv4,或者修正 DNS 记录来绕开问题。

2.4 抓取机制限制:更新频率、超时、抓取后端

即使网络完全通,TT-RSS 也可能因为自身配置限制导致导入失败。它默认的抓取间隔是按全局配置来算的,如果你把 RSSHub 源放进一个更新特别频繁的类别里,RSSHub 的上游站点或者你自建的 Redis 缓存非常容易触发限流。

另外,TT-RSS 的抓取后端是 PHP 的 curl,默认超时时间在部分环境里很短,RSSHub 某些路由又特别慢——比如查一个跨度很大的作者文献,上游要翻很多页,Nginx 都等得失去耐心了,TT-RSS 自然只能报超时。这种情况建议先用 curl 量一下这个路由的完成时间:

curl -L -o /dev/null -s -w "耗时:%{time_total}s" "https://你的RSSHub域名/慢路由"

如果耗时大于 30 秒,那 TT-RSS 报超时的频率会很高,最好换参数缩小返回范围,或者适当调大 PHP 和 Web 端的超时上限。

2.5 反向代理与缓存拦路

RSSHub 自建通常都会套一层 Nginx 或者 Caddy 来加密 HTTPS。反向代理本身没问题,但如果你给 RSSHub 域名配置了强制缓存,问题就来了。TT-RSS 请求某个路由后,Nginx 可能会把一段“过期的内容”缓存下来,后续 TT-RSS 无论怎么刷新拿到的都是旧 XML,而 RSSHub 那边的实际数据早就更新了。你甚至在 TT-RSS 里永远看不到新文章,但直接 curl 源地址又明明是新的。

排查方法就是绕过反向代理直接访问 RSSHub 原生端口:

curl -I "http://127.0.0.1:1200/你的路由" curl -I "https://你的域名/你的路由"

两者结果明显不一致,那就是反代层出了问题,需要在 Nginx 配置里对 RSSHub 的 location 关闭 proxy_cache。特别提示:RSSHub 自带的响应头里有Cache-Control之类的字段,反代如果忽略它而使用自己的缓存策略,就会埋坑。

3. 手动复现 + 修复:从零到一

3.1 在服务器上先确认 RSSHub 是否活着

先进入 RSSHub 所在机器,确认容器和端口状态:

docker ps | grep rsshub ss -ltnp | grep 1200

ss输出里能看到 1200 端口有进程监听,基本说明 RSSHub 容器在跑。再随便请求一个普遍可用的路由,比如首页聚合路由,确认服务能吐 XML:

curl -L -o /dev/null -s -w "%{http_code}\n" "http://127.0.0.1:1200/动物/猫咪/热门"

我故意挑中文路由是因为中文参数能同时验证 URL 编码问题是否存在于反代层。返回 200 就继续,返回 404 就去 RSSHub 的 docs 页面确认这个路由是否已经变更或者需要额外参数。

3.2 从外部和 TT-RSS 内部双向验证

RSSHub 服务端确认没问题后,切换到 TT-RSS 服务器,验证该服务器能不能访问 RSSHub:

curl -L -o /dev/null -s -w "HTTP %{http_code},耗时 %{time_total}s\n" "https://你的RSSHub域名/刚才那个路由"

如果你是在 Docker 里跑的 TT-RSS,建议直接进入容器验证:

docker exec -it 你的ttrss容器名 sh curl -L "https://你的RSSHub域名/某个路由"

这里有个小技巧:TT-RSS 容器里的基础镜像不一定带 curl,只有 wget 或者什么都没有。可以先用apt update && apt install curl装上,或者改用 PHP 自带函数测试。如果容器里访问不通而宿主机访问通,十有八九是 Docker 网络模式的问题——最简单的解法是让 TT-RSS 和 RSSHub 共用同一个 Docker 网络,TT-RSS 里填http://rsshub容器名:1200/路由,速度和稳定性反而比走公网好。

3.3 开启调试,让 TT-RSS 自己说出原因

TT-RSS 最冤枉的一点是它把所有失败都压缩成“更新失败”或“错误 数字”这种极简提示,用户看不到底层 curl 的具体返回。好在 TT-RSS 有调试模式,打开它就能拿到真实错误码。

在 TT-RSS 的 config 里找到类似set('LOG_DESTINATION', ...)的地方,把日志级别调高;同时去“偏好设置”里找到“调试”相关选项,或者直接用命令行方式手动更新一个源:

cd 你的TT-RSS目录 php update.php --feeds=你要调试的源ID --debug

调试输出会显示实际执行的 curl 请求、HTTP 状态码、响应头,甚至能直接看到 RSSHub 返回的 XML 开头内容。我靠这个方法查出过好几次“请求带了多余的百分号编码”和“TT-RSS 自动给地址拼了/feed后缀”的幺蛾子——这些在界面上基本看不出来。

3.4 把修复动作固化

问题定位后,别只靠手动测试,建议把这些经验固化到配置文件里。比如在 TT-RSS 里,把 RSSHub 源的更新间隔设置为一个更保守的值,防止短时间大量源同时刷新时互相拖垮;在 RSSHub 的.env里适当调大缓存时间,减少上游站的瞬时压力。

如果问题出在路由参数上,最后提交到 TT-RSS 的地址要控制在“浏览器里直接打开能看到一条条文章”的状态,并且要用完成的 URL 编码形式。比如中文参数写成%E4%BD%9C%E8%80%85,而不是直接粘中文。我可以写个小脚本批量生成最终 Feed 地址,后续换作者、换关键词时直接套用,省得每次手工编码。

4. 常见问题速查表 + 独家避坑笔记

4.1 一张表看清现象、原因和动作

TT-RSS 报错/现象最可能的根因验证方法推荐解决动作
错误 404路由路径错误/参数未编码curl 后台直接访问路由对照文档矫正路由,中文参数做 URL 编码
错误 0 或 cURL 超时抓取超时 / 慢路由curl 加-w看耗时换更快参数、调大超时、缩小查询范围
能导入但一直是 0 篇路由返回空 Feed/新文章没匹配规则浏览器直接打开看内容重新校验参数和返回结构
429更新过于频繁/触发限流看 RSSHub 日志是否有 429调大更新间隔,或改缓存
内容全都可以,但更新很慢反代缓存 / 上游较慢对比直连与域名访问耗时关闭 RSSHub 相关 location 的缓存
容器访问不了宿主机Docker 网络隔离进入容器 ping/curl改用容器名或宿主机内网 IP

这张表是我实测中最高频的六种情况,基本覆盖了“TT-RSS 无法导入 RSSHub 源”这个问题的九成场景。

4.2 几条穿坑很久才懂的经验

第一,不要迷信“浏览器能打开就等于 OK”。浏览器和 curl 在 HTTP 请求头、缓存策略上都不同,TT-RSS 更像 curl。以后看到浏览器正常,先别高兴太早,去服务器上 curl 一次才靠谱。

第二,TT-RSS 的“更新源”按钮并不总是会立刻去服务器抓取。如果你改完路由后马上点更新,它可能还在走缓存队列,看起来像没变化。我一般改完会儿参数会等一下再点,或者直接用 php update.php 强制刷新,能避免很多误判。

第三,RSSHub 官方文档里的示例域名并不等于你自己部署的地址。新手最容易犯的错就是把rsshub.app的 URL 直接填进 TT-RSS,如果这个源在官方路由里已经限流,就永远导不进去。这一条不算技术坑,但极其常见。

第四,当你同时订阅很多来自 RSSHub 的源,尽量在源地址的后缀中带上具体参数,而不是动态拼接。TT-RSS 对包含特殊字符的 URL 处理偶尔会出错,尤其是&字符,如果不加引号或者不做转义,PHP 解析时会静默截断,然后你就会看到一个只有前半段的错误地址。

5. 进阶玩法:用 RSS 追踪特定作者文献

5.1 为什么“订阅作者”会比“刷关键词”更省心

最近很多人开始研究怎么用 RSS 追踪特定作者的最新文献,这个需求高频出现在科研场景:盯住某个大牛的课题组动态,或者跟踪某位竞争者的发文情况。相比反复去数据库搜关键词,把“这个人”做成一类独立 Feed 的好处很明显:

  • Feed 天然有“新增/未读”状态,新文献一来你立刻能感知。
  • 可以并行订阅多位作者,互不干扰,TT-RSS 的分类和标签机制还能自动归档。
  • 不需要每天打开数据库网站重复检索。

用 RSSHub 搭这条路,核心思路是:找到相关的路由,用作者的姓名或 ID 作为参数生成一条 Feed,然后把这条 Feed 交给 TT-RSS 统一管理。

5.2 按这套思路组合出来一个作者跟踪源

具体路由要以你部署的 RSSHub 版本文档为准,但操作方法基本一致:先在 RSSHub 的路由列表里搜索“arxiv”、“scholar”或“citation”这类关键词,找到能按作者检索的路由,照着示例把作者姓名替换进去,再对中文或特殊字符做 URL 编码。

以文献追踪场景为例,最终得到的地址形式通常是:

https://你的RSSHub域名/arxiv/query/au:作者名缩写+AND+ti:某方向/1

这条 Feed 放进 TT-RSS 之前,我先在浏览器打开确认条目数量不为 0,然后用 curl 测一遍耗时,如果太慢就缩小时间范围或者减少关键词组合。TT-RSS 里的源名称我会写成人名加备注,比如“张三 - 分布式系统”,方便后续筛选。

如果你追踪的目标期刊也提供官方 Feed,那就没必要绕道 RSSHub,直接订阅官方渠道反而更稳。RSSHub 适合用于那些不提供 RSS 的数据库或期刊聚合平台。

5.3 在 TT-RSS 里维护这些源的小建议

作者跟踪源一旦建起来,数量会很快膨胀。我建议在 TT-RSS 里专门建一个“作者追踪”分类,然后给每位作者标签上写明研究领域。更新间隔可以设置成几小时一次,文献类源不需要像新闻那样实时刷新,太频繁反而容易触发上游限流。

维护过程中,如果某条源连续几周都没有更新,先别急着删。先用浏览器手动打开一次,确认该作者的确没有新文献——很多高校团队更新慢是正常的,动不动就删源反而会错过后续的关键动态。我还会把 RSSHub 的缓存日志开起来,看到某条源频繁回源时,就知道上游可能在变化。

TT-RSS 的全文抓取功能对文献源也很有用,开启后可以直接把摘要抓进阅读器,省去跳到原网站的步骤。但要注意,某些学术数据库会防爬,抓多了容易遇到验证页,这时候就把全文抓取关掉,只看摘要和标题就够了。

用 RSS 追踪特定作者这件事,本质上就是把你每天被动刷网页的动作自动化掉。TT-RSS 加 RSSHub 这套组合,配置好了以后真的是一劳永逸。我也踩过不少坑,但从第一次成功把作者文献 Feed 拉进来后,我再也没落过任何重要更新。希望这篇经验能帮你少走点弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询