- 后端
- 前端
- 网页爬虫
- MCP 服务
- AI 技能
【免费下载链接】AnimeGarden
動漫花園 镜像站 | 动画 BT 资源聚合站 | 动画 BT 资源开放接口
AnimeGarden 是動漫花園的镜像站与动画 BT 资源聚合站,除了网页端,还对外提供一套无需鉴权的 JSON HTTP 开放接口,覆盖状态查询、资源搜索、资源详情、收藏夹(Collection)以及用户/字幕组/番剧元数据五类能力。本文以仓库中的接口参考文档 api.md 为核心,逐接口讲清 Base URL、分页约定、全部查询参数与响应结构,并结合 服务端路由实现 与 @animegarden/client SDK 的源码,说明参数解析、查询语义和缓存策略等实现细节,读完即可直接用curl或 SDK 编写可靠的资源抓取与聚合程序。
一、Base URL、鉴权与总体响应约定
接口的 Base URL 为:
https://api.animes.garden- 本文档覆盖的公开端点均不需要任何鉴权(仓库中
/admin/*管理端点使用 Bearer Token 鉴权,属于运维内部接口,不在开放接口范围内,见 admin.ts); - SDK 的默认
baseURL即https://api.animes.garden/,见 constants.ts 中DefaultBaseURL的定义; - 服务端对所有开放接口启用了 CORS(
origin: '*'),并附带X-Request-Id、X-Response-Timestamp等诊断响应头,请求整体有 60 秒超时,超时返回408与{ status: 'ERROR', message: 'Request timeout after waiting 60 seconds...' },见 server/index.ts。
1.1 状态码与错误模型
响应体约定遵循统一的status字段模式:
- 成功响应通常带
status: "OK"; - 错误响应通常带
status: "ERROR"和message,例如详情接口的message会是Unknown detail id: dmhy 123; - 未匹配到资源时,服务端还可能返回
{ status: 'ERROR' }配合500状态码,见全局错误处理器 server/index.ts。
1.2 分页对象 pagination
资源列表的分页信息统一放在pagination对象中:
interface PaginationResult { page: number; // 从 1 开始 pageSize: number; // 请求的每页条数 complete: boolean; }page从1开始;pageSize是请求的每页条数,实际返回的资源条数可能更少(最后一页常见);complete: true只表示"当前页之后没有更多匹配资源",不代表调用方已经取遍了之前各页。
服务端在解析分页参数时会做归一化:page非法或小于1时回落到1;pageSize非法、小于1或超过MaxRequestPageSize(1000)时回落到DefaultPageSize(100),见 resolver.ts 与 constants.ts。
此外,resources-query.ts 定义了深分页保护:当(page - 1) * pageSize + pageSize > 10000时抛出ResourcesDeepPaginationError,接口返回400;慢查询繁忙返回503,慢查询超时返回504。也就是说,即使pageSize=1000,page最多也只能推进到offset不超过约 1 万条的位置,超出时请改用时间窗口(before/after)收窄查询。
二、状态 API:GET /
用于获取 API 状态、当前时间戳与上游 provider 的健康状况:
- 参数:无;
- 响应:
200,包含status: 'OK'、timestamp(上游数据时间戳)、providers(各 provider 的健康状态),以及指向openapi.json与llms.txt文档的发现链接links,见 server/index.ts;另有结构几乎相同的/health端点可供探活。
curl 'https://api.animes.garden/'providers里的四个上游(dmhy、moe、mikan、ani)即本项目全部受支持的 provider 常量SupportProviders,见 constants.ts。
三、资源 API
3.1 GET /resources:多条件资源检索
GET /resources是核心查询端点,支持 query-string 参数,也支持 JSON body(服务端通过ctx.req.json().catch(() => undefined)同时解析两者,body 优先,见 resources.ts)。路由本身注册了/resources、/resources/、/resources/:page以及按 provider 限定的/resources/{provider}、/resources/{provider}/:page等变体。
查询参数一览(query 参数均可重复出现,多值字段在同字段内是OR关系):
| 参数 | 说明 | 备注(源码补充) |
|---|---|---|
page | 页码,从1开始 | 默认1;非法值回落1 |
pageSize | 每页条数 | 默认100,最大1000,超限回落默认值 |
after | 时间下界,保留创建时间不早于该时刻的资源 | 接受日期字符串或毫秒时间戳,服务端用 zodcoerce.date解析 |
before | 时间上界,保留创建时间不晚于该时刻的资源 | 同上 |
search | 全文检索词,匹配标题/内容 | 可多值;search存在时会覆盖include(优先级更高) |
include | 标题包含匹配词,search的轻量替代 | 可多值,命中其一即可 |
keyword | 必需关键词;重复该参数表示多个必需词 | 全部命中(AND 语义) |
exclude | 屏蔽词;命中的资源被剔除 | 只要命中任一屏蔽词即剔除 |
type | 资源分类过滤(如 动画、合集、音乐) | 可多值,同字段内 OR |
subject | Bangumi 番剧 ID 过滤 | 可多值,同字段内 OR |
fansub | 字幕组名称过滤 | 可多值,同字段内 OR |
publisher | 发布者/上传者名称过滤 | 可多值,同字段内 OR |
tracker | 是否将 magnet 的 tracker 值返回 | 取值为true/yes/on(不区分大小写)时启用,否则响应中会删除tracker字段 |
metadata | 是否返回解析后的元数据(如anipar结果) | 取值同上;数据库列类型即{ anipar?: ParseResult },见 schema/resources.ts |
tracker与metadata的开关逻辑在 resources.ts:默认都关闭,只有当查询参数值属于['true', 'yes', 'on'](小写比较)时才保留对应字段,否则从每条资源上删除。
响应结构(200,ResourcesResponse):
{ "status": "OK", "resources": [ /* Resource[] */ ], "pagination": { "page": 1, "pageSize": 30, "complete": false }, "filter": { /* 服务端解析归一化后的筛选条件 */ }, "timestamp": "2024-01-01T00:00:00.000Z" }注意响应中没有与resources同级的顶层complete字段,完成度只存在于pagination内。
Resource对象的字段(SDK 类型定义,见 types.ts):
| 字段 | 说明 |
|---|---|
id | 站内资源主键 |
provider/providerId | 上游来源与上游侧 ID |
title/href | 资源标题、上游详情页链接 |
type | 资源分类(动画、合集、音乐等) |
magnet | magnet 链接 |
tracker | 仅在tracker=true时返回 |
size | 资源大小(字节) |
fansub | 字幕组{ id, name, avatar },可为空 |
publisher | 发布者{ id, name, avatar } |
subjectId | 关联的 Bangumi 番剧 ID,可为空 |
createdAt/fetchedAt | 资源创建时间 / 服务端抓取时间 |
metadata | 仅在metadata=true时返回,含anipar解析结果 |
curl 示例(摘自 api.md 原文,URL 编码后的中文条件):
# 搜索「葬送的芙莉莲」,必需词 1080p / 简体内嵌,类型限定动画 curl 'https://api.animes.garden/resources?search=%E8%91%AC%E9%80%81%E7%9A%84%E8%8A%99%E8%8E%89%E8%8E%B2&keyword=1080p&keyword=%E7%AE%80%E4%BD%93%E5%86%85%E5%B5%8C&type=%E5%8A%A8%E7%94%BB&page=1&pageSize=30'仓库 examples/api.http 中还有更多可直接运行的组合,例如:
### 按时间窗 + 字幕组/发布者过滤 GET https://api.animes.garden/resources?type=动画&fansub=LoliHouse&publisher=LoliHouse&after=2023-04-16T13:00:00.000Z&before=1681653600000 ### 多字幕组 OR 过滤 GET https://api.animes.garden/resources?fansub=ANi&fansub=爱恋字幕社 ### 带复杂组合条件的 JSON body 查询 GET https://api.animes.garden/resources?type=动画 Content-Type: application/json { "include": ["机动战士高达", "水星的魔女"], "keywords": ["第二季", "ANi"] }查询语义(重点),来自文档 Notes 并经 resolver.ts 源码印证:
- 不同查询组(type、subject、fansub/publisher、时间窗、标题条件)之间是AND关系;
fansub、publisher、type、subject、include等多值字段在同一字段内是 OR关系;search优先级高于include:解析器在filter.search非空时会直接delete filter.include(resolver.ts);keyword是必需词(AND 语义),exclude是屏蔽词,命中即剔除;- 标题匹配前会先做归一化:全角转半角、繁体转简体(
normalizeTitle,见 utils.ts),因此中英文标点混用、繁简差异不影响匹配。
3.2 GET /detail/{provider}/{id}:单资源详情
获取某条资源的完整详情(描述、文件列表、多 magnet):
- 路径参数:
provider:dmhy|moe|mikan|ani;id:上游侧资源 ID 字符串(例如 dmhy 的帖子 ID);
- 响应:
200返回{ status, resource, detail, timestamp },其中detail为ResourceDetail:description(种子描述)、files[]({ name, size })、magnets[]({ name, url })、hasMoreFiles(文件列表是否还有更多),类型见 types.ts; - 未找到时返回错误:源码对无法解析的 ID 返回
400,对库中不存在的详情返回404,两者响应体均为{ status: 'ERROR', message: 'Unknown detail id: ...' }并设置Cache-Control: no-store;成功响应缓存Cache-Control: public, max-age=86400(24 小时),见 resources.ts。
curl 'https://api.animes.garden/detail/dmhy/123456'实现上,详情查询走了memo内存缓存(TTL 1 小时、有容量上限与自动 GC,cacheErrors: false不缓存错误),避免对同一provider:id重复打上游,见 resources.ts。
3.3 GET /detail/infohash/{hash}:按 Info Hash 查询
用 torrent 的 info hash 反查资源与详情,适合从磁力链接提取 hash 后直接换取结构化数据:
- 路径参数
hash:40 位十六进制([0-9A-F]{40})或 32 位 base32([A-Z2-7]{32})info hash,大小写不敏感(源码先toUpperCase再校验,见 resources.ts); - 响应:
200返回{ status, resource, detail, timestamp }; - 非法 hash 返回
400+status: 'ERROR'、Invalid info hash: ...;hash 合法但库中不存在时返回404+Unknown detail info hash: ...。处理这类详情查询时,应把400/404的ERROR统一视为"输入无效或未找到"。
四、Collection API:GET /collection/{hash}
Collection 是"保存好的多组筛选条件 + 每组的第一页结果",适合把一套常用订阅条件固化成可分享的 hash。
4.1 创建与获取
- 创建:
POST /collection或PUT /collection,body 为{ name, authorization, filters[] },服务端对 collection 内容做哈希后落库,返回{ status, id, hash, createdAt };重复提交相同内容不会重复建库(onConflictDoNothing)。见 collections.ts 与 collections/index.ts; - 获取:
GET /collection/{hash},其中hash为创建时返回的 collection hash。该端点不接受page/pageSize参数。
4.2 响应结构
200返回{ status, hash, name, createdAt, filters[], results[] }(源码另附updatedAt),其中results[i]与filters[i]一一对应,包含:
resources[]:该组筛选条件命中的资源(第一页);pagination:固定为{ page: 1, pageSize: 1000, complete: boolean }——每个 filter 固定取第 1 页、每页至多1000条,见 collections/index.ts(query.find(f, { page: 1, pageSize: 1000 }));filter:解析归一化后的资源查询条件。
results[i]上没有与resources同级的complete字段,完成度在pagination内。服务端对该接口结果有 5 分钟的 memo 缓存。
4.3 获取更多资源
当results[i].pagination.complete为false时,取下一页的正确姿势是:
- 取出对应
filters[i].searchParams(服务端已拼好的查询串); - 调用
GET /resources,在searchParams基础上追加page(下一页,即results[i].pagination.page + 1)与相同pageSize(1000)。
Collection 查询本身永远返回page=1,所以"翻页"必须回到/resources完成。
4.4 分页字段迁移(破坏性变更)
旧的完成度字段已移除且不保留别名:
| 旧响应路径 | 新响应路径 |
|---|---|
/resources:result.complete | result.pagination.complete |
/collection/{hash}:result.results[i].complete | result.results[i].pagination.complete |
SDK 同样为资源与 collection 查询结果暴露pagination对象。调用方、fixtures 与断言都应改为从pagination读取全部分页字段。迁移细节(含 SDK 侧CollectionFilter结果态的filter.complete→filter.pagination.complete)在 pagination.md 中有更完整的说明。
五、元数据 APIs
5.1 GET /users:发布者列表
- 参数:无;响应:
200,{ status, users[] },列表项含id、名称、avatar等; - 路由实现见 users.ts,数据来自内存中的
UsersModule.ids索引,响应缓存Cache-Control: public, max-age=86400; - 从源码结构看,
users[]每项对应users表一行:id、name(规范名)、avatar、providers(provider →{ providerId, avatar?, aliases? }的映射),见 schema/users.ts。同一个人在不同上游的旧名称会被归一化为aliases(见 normalize.ts 所在的规范化逻辑),因此按providerId匹配比按name匹配更稳定。
curl 'https://api.animes.garden/users'5.2 GET /teams:字幕组列表
- 参数:无;响应:
200,{ status, teams[] },结构与/users对称(id、名称、avatar、各 provider 侧身份); - 路由与 users.ts 中的
/teams一致,数据源为teams表,缓存策略相同(24 小时)。
curl 'https://api.animes.garden/teams'5.3 GET /subjects:番剧列表
- 参数:无;响应:
200,{ status, subjects[] },列表项含 Bangumi 主题 ID、名称、检索词、activedAt、isArchived; - 实现见 subjects.ts:返回的是
SubjectsModule.activeSubjects,即仅未归档(isArchived === false)的主题,见 subjects/index.ts; - 从源码结构看,
subjects表以bangumi_id为主键(id即 Bangumi 主题 ID),另存search检索词 JSON、actived_at与is_archived,见 schema/subjects.ts。这些subjectID 可直接用于/resources?subject=...过滤。
curl 'https://api.animes.garden/subjects'六、配套 SDK:@animegarden/client
服务端仓库自带 TypeScript SDK packages/client,HTTP 层行为与本文各端点一一对应:
fetchResources(options):封装/resources;设置count(-1表示取全部匹配)时会以pageSize=1000连续翻页直到pagination.complete或取满count,按href去重并按createdAt降序输出,见 api/resources.ts;fetchResourceDetail(provider, id)/fetchResourceDetailByInfoHash(hash):分别封装两个详情端点,见 api/detail.ts;fetchCollection(hash)/generateCollection(collection):封装 collection 查询与创建,提交时会自动剔除 filters 里的resources、pagination等客户端查询态字段,只保存筛选条件本身,见 api/collection.ts;- 通用请求选项
FetchOptions支持自定义fetch、baseURL(默认https://api.animes.garden/)、retry(默认 0)、timeout、signal与 hooks,见 types.ts。
SDK 的高级 API 统一返回ClientResult:成功为{ ok: true, ...数据 },失败为{ ok: false, code, error },错误码覆盖NOT_FOUND、BAD_REQUEST、RATE_LIMITED、SERVER_ERROR、NETWORK_ERROR、TIMEOUT、ABORTED、INVALID_RESPONSE,并标注是否可重试;完整模型与取消/超时归类规则见 error-model.md。多页请求失败时会保留已取回的部分resources与pagination,便于降级展示。
七、使用要点小结
- 分页:从
page=1逐页推进,pageSize建议不超过1000,并始终检查pagination.complete;深分页(offset 超过约 1 万条)会收到400,此时改用after/before时间窗切片; - 查询语义:字段间 AND、字段内 OR;
search会覆盖include;keyword全命中、exclude命中即剔除; - 按需取字段:
tracker、metadata默认不返回,需要 magnet tracker 或anipar解析结果时显式传tracker=true/metadata=true; - 详情兜底:
/detail/{provider}/{id}与/detail/infohash/{hash}的400/404都应按"无效输入或未找到"处理;成功结果有 24 小时缓存(max-age=86400),不适合秒级刷新场景; - Collection 翻页:collection 端点只给第一页(每 filter 至多 1000 条),继续取数请用
filters[i].searchParams回查/resources; - 迁移注意:旧的顶层
complete字段已删除,所有完成度判断都改读pagination.complete。
以上端点、参数与响应结构的原始出处是仓库内的接口参考文档 api.md,可复现的请求样例集中在 examples/api.http,分页与错误模型的补充文档见 pagination.md 和 error-model.md。
- 后端
- 前端
- 网页爬虫
- MCP 服务
- AI 技能
【免费下载链接】AnimeGarden
動漫花園 镜像站 | 动画 BT 资源聚合站 | 动画 BT 资源开放接口
相关推荐
CoolQ HTTP API 接口详解与使用指南
CoolQ HTTP API 接口详解与使用指南 项目概述 CoolQ HTTP API 是一个为 QQ 机器人框架 CoolQ 设计的 HTTP 接口插件,它
CoolQ HTTP API 接口详解与使用指南
CoolQ HTTP API 接口详解与使用指南 项目概述 CoolQ HTTP API 是一个基于 HTTP 协议的 QQ 机器人接口,允许开发者通过 HTT
bk-cmdb 根据 ID 列表拉取缓存资源详情(list_cached_resource_by_ids)接口实战指南
bk cmdb 根据 ID 列表拉取缓存资源详情(list_cached_resource_by_ids)接口实战指南 本文面向蓝鲸智云配置平台(bk cmdb
后端企业应用运维
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考