2026 年的 Jikan:非官方 MyAnimeList API 能做什么,以及只有官方 API 能做的那一件事
搜「MyAnimeList API」会冒出两个完全不同的东西,而且人们一直选错。Jikan 是非官方 REST API:无 key、无 OAuth,覆盖所有公开的动画与漫画数据,限速 3 req/s、60 req/min,从 24 小时缓存里返回。官方 MAL API v2 需要 OAuth2 和注册的 Client ID,但它是唯一能读写某个登录用户自己列表的那个。分界线不是质量,是你要不要碰用户的账号。
上面是文章摘要,下面进入正文深读。可以配合目录逐段阅读,不会丢掉上下文。
一个做追番应用的开发者跟我说,他在写第一个功能之前,先在 OAuth 上耗掉了一整天。他搜「MyAnimeList API」,落到官方开发者文档,注册了应用,把 OAuth2 授权码流程连同 redirect URI 和 token 刷新全都接好,终于拿到了 access token。然后他用这个 token 做了他 MVP 第一天唯一真正需要的事:展示某部动画的简介、评分和封面。这些字段全是公开的。他为了取没有任何登录保护的数据,搭了一整套登录流程。
MyAnimeList 有两个 API,而几乎没人告诉你:在它们之间怎么选,跟哪个更好毫无关系。非官方的 Jikan,和官方的 MyAnimeList API v2(那个 OAuth2 的),沿着一条大多数教程从不画出的线干净地分开:你的功能碰不碰某个具体用户自己的账号? 一边是公开的动画信息,另一边是登录用户的个人列表。把这条线划对,剩下的决定就自己成立了。
两个 API,放在一屏里
这不是同一个产品的两种口味。它们是两个不同的服务,各自解决问题的不同一半。
| Jikan(非官方) | 官方 MAL API v2 | |
|---|---|---|
| 基址 | https://api.jikan.moe/v4 |
https://api.myanimelist.net/v2 |
| 认证 | 无 | 公开读取要 X-MAL-CLIENT-ID,用户操作要完整 OAuth2 |
| 注册 | 不需要 | 需要(注册应用拿 Client ID) |
| 读公开数据 | 能,全部 | 能 |
| 读用户自己的列表 | 仅公开档案数据 | 能,用该用户的 token |
| 写用户的列表 | 不能,永远不能 | 能,唯一能做的 |
| 限流 | 3 req/秒,60 req/分 | 未公布;安全假设是约 1 req/秒 |
| 数据新鲜度 | 缓存,最旧 24 小时 | 实时 |
| 费用 | 免费,靠捐赠 | 免费 |
决定一切的是「写用户的列表」这一行。Jikan 在这里是硬性的「不能」,再聪明也改不了。官方 API 是唯一的「能」。其余的一切都只是便利程度的问题。
Jikan 到底是什么
Jikan 是一个开源 REST API,它从 MyAnimeList.net 读取公开数据,再以干净的 JSON 重新提供。名字来自日语「時間」,这个项目存在只有一个原因:MyAnimeList 多年没有可用的公开 API,于是社区靠读取站点、把结果暴露出来,自己造了一个。今天它以 PHP/Laravel 应用运行,当前版本是 v4,公共实例在 https://api.jikan.moe/v4。
最招牌的特性是零摩擦。没有 API key、没有账号、没有 OAuth、没有 Authorization 头。你发个 GET 请求,就拿到 JSON。下面这条现在就能跑,从你的终端,什么都不用配:
curl "https://api.jikan.moe/v4/anime/1"
它返回《星际牛仔》的完整记录:多语言标题、简介、评分、排名、集数、放送日期、制作公司、类型等等。端点面很广,且贴合人们实际浏览动画的方式:/anime 和 /manga 做搜索和详情,/characters 和 /people 做角色和制作人员,/seasons/now 拿当前季度的番表,/schedules 看每个工作日放送什么,/top/anime 取排行,/genres/anime 做类型筛选,/producers 看制作方,外加 /random、/recommendations 和 /reviews。对一个「浏览 + 发现」类产品,这基本覆盖了你想展示的一切。
Jikan 不是什么:它不是实时镜像,也不是写入面。它读的是公开页面,所以看不到任何私有内容,也无法以任何人的身份认证。这一个特性,既是它最大优势的来源(你什么都不用准备就能用),也是它唯一硬限制的来源(它永远碰不到用户的账号)。
限流,以及你必须围着它设计的 24 小时缓存
公共 Jikan 实例同时执行两个限制:每秒 3 次、每分钟 60 次。 两个都生效,所以一秒内突发 5 个请求会触发每秒限制,哪怕你那一分钟离 60 还远。超过任一个就收到 HTTP 429。没有公布的每日上限,但把每分钟天花板当成你真正的预算,是对的心智模型。(如果你看到老代码或教程假设每分钟 30 次,那是 v3,已废弃;v4 翻倍到了 60。)
第二件要围着设计的是新鲜度。Jikan 返回缓存数据,默认缓存寿命 24 小时(配置里是 CACHE_DEFAULT_EXPIRE=86400,部分端点有自己更短的过期时间)。对人们要做的 95% 的东西,这既隐形又是好事:动画简介、评分、声优表几乎不变,而正是缓存让一个免费、靠捐赠的服务撑得下去。但这意味着 Jikan 不适合任何需要分钟级准确的东西。一部一小时前刚播的剧集的全新评分,或者用户三十秒前刚改的列表,不会立刻反映出来。如果你功能的价值取决于实时数据,那就是个信号:这个功能你用错 API 了。
这两个事实合起来是一个清晰的使用模式:在你自己这边缓存 Jikan 响应,给请求做 key 以免反复重取同一部动画,并稳稳压在 60/分钟以下。项目靠捐赠运营,它希望你体贴而不是向你收费,所以激进的客户端缓存不只对你的延迟有好处,它是隐含的约定。
官方 MAL API v2:唯一能写的那个
官方 API 是你在 MyAnimeList 开发者设置里注册的那个,它和 Jikan 有两处关键不同。第一,即便读公开数据也要标明你的应用:你注册一个应用,拿到 Client ID,作为 X-MAL-CLIENT-ID 头发送。少了这个头,公开读取会以未授权错误失败。第二,任何涉及具体用户的操作(读他的列表、更新追番状态、改评分)都需要完整的 OAuth2 授权码流程——用户登录并授权你的应用,你拿到一个绑定该用户的 access token。
对大多数开发者来说,这条 OAuth2 路径正是官方 API 存在的全部理由。它是唯一能做到这些的方式:
- 读一个登录用户的动画或漫画列表,包括私有条目
- 更新用户的状态(在看、看完、搁置、抛弃、想看)
- 设置或修改用户对某部作品的评分
- 往用户列表里增删条目
这些 Jikan 一个都做不到,是设计如此。所以如果你做的东西要让用户用 MyAnimeList 账号登录、并由你的应用读取或修改他们的个人列表,那官方 API 就不是可选项,不管 Jikan 调起来多舒服。
代价是实打实的摩擦。你从「发个 GET 请求」变成「注册应用、实现 OAuth2、处理 redirect URI、存储和刷新 token、管理每用户的 scope」。这是相当一笔工作量,而如果你的功能根本不碰用户账号,这就是白费的工作——又绕回开头那个开发者损失的一天。
那到底选哪个?
决定坍缩成一个问题,而且你应该逐功能回答,而不是为整个应用回答一次。
这个功能碰不碰某个具体用户自己的 MyAnimeList 账号?
如果不碰(搜索、动画和漫画详情页、季度番表、Top 100 排行、角色和制作人员页、类型浏览、「周二播什么」),用 Jikan。没有任何理由为了展示没有登录保护的数据去扛 OAuth2 和应用注册。零认证,完整公开目录,搞定。
如果碰(登录用户的个人列表、他的评分、把某部标记为已看、同步他的想看清单),用 官方 API v2 加 OAuth2。只有它能以那个用户的身份认证,所以没有替代方案。
而对很多真实应用,答案是「两个都用」。一个典型的追番应用,用 Jikan 撑起整个公开目录(这样用户能搜索和浏览一个又深又丰富的数据集,而你从不用申请 key),只在登录用户读写自己列表那一薄片上用官方 API。公开的那 90% 享受 Jikan 的零摩擦广度,只为真正需要的那 10% 付 OAuth2 的代价。
当每分钟 60 次不够:自托管 Jikan
如果你的公开数据需求超出了共享实例的 60/分钟,你不换 API,而是跑自己的 Jikan。整套东西是开源的(jikan-me/jikan-rest),并以容器镜像分发:
docker run -d --name jikan-rest -p 8080:8080 \
-v ./.env:/app/.env jikanme/jikan-rest:latest
不过一套完整的自托管不止一个容器。这个服务需要 web 服务器、定时任务、以及用于缓存和搜索索引的队列 worker,加上一个缓存后端(它支持 Redis 和文件缓存,24 小时的默认过期可通过 CACHE_DEFAULT_EXPIRE 配置),可选还有 MongoDB。把这些接在一起的 docker-compose 配置是现实的路径。回报是你设自己的限流、延迟由你自己掌控,同时打的还是同一份 MyAnimeList 数据。自托管不改变只读的本质:自托管的 Jikan 仍然写不了用户列表,因为它仍然没有用户认证。自托管唯一买到的是吞吐。
接起来:每家的请求
Jikan,无认证,就一个 GET:
curl "https://api.jikan.moe/v4/anime?q=frieren&limit=5"
官方 API,读公开数据,要带你注册的 Client ID:
curl "https://api.myanimelist.net/v2/anime?q=frieren&limit=5" \
-H "X-MAL-CLIENT-ID: YOUR_CLIENT_ID"
官方 API,读登录用户自己的列表,要带用户授权后你拿到的 OAuth2 access token:
curl "https://api.myanimelist.net/v2/users/@me/animelist?status=watching" \
-H "Authorization: Bearer USER_ACCESS_TOKEN"
这三行的形态就是整篇文章的缩影。第一行什么都不需要。第二行需要你注册过。第三行需要一个真人登录过并说了「同意」。
上线前
一份把 MyAnimeList 数据从原型接到生产的精简清单:
先按「用户自己的账号」这条线把功能分开。 列出每个功能,逐个标成公开数据还是用户账号,你立刻就能看出哪些要 Jikan、哪些要官方 OAuth2 API。大多数追番应用绝大部分落在 Jikan 这边。
别为公开数据搭 OAuth2。 如果一个功能只展示任何人不登录就能看到的动画和漫画,Jikan 直接消掉了整个认证问题。把 OAuth2 留给真正读写用户列表的功能。
在你这边缓存 Jikan 响应,并节流到 60/分钟。 每秒 3 次、每分钟 60 次的限制是真的,而且服务靠捐赠。按资源 ID 缓存以免重取同一部动画,你就很少会撞 429。
把 Jikan 数据当作最旧 24 小时陈旧来对待。 它从缓存返回。这对简介和排行没问题;对任何需要实时准确的东西就不对。需要实时,那个功能该放在官方 API 上。
超出公共实例就先自托管,别急着重构架构。
jikan-rest开源且已 Docker 化。跑自己的副本能在不改一行客户端代码的情况下抬高限流,但记住它仍然是只读的。
想要每个 MyAnimeList API 暴露什么、当前限制是多少的并排对比,Jikan 工具页 和 官方 MyAnimeList API 页 有版本最新的汇总。相邻的目录与娱乐数据服务,媒体分类 列出了目录里的其余条目。
快速跳到对应段落
下一步
读完后可以继续回到工具目录,对比具体产品。
去看工具