兼容 TMDB v3 和 OMDb 的电影 API
amodb 是独立的电影 API。它使用与 TMDB v3 和 OMDb 相同的协议,因此为其中任何一个编写的客户端,只要把基础 URL 改为 https:/(OMDb 风格的调用则用 https:/)就能工作。你用 /search/movie 找到电影,再用 /movie/{movie_id} 和 append_to_response 读取它。
你会得到:
- TMDB v3 结构的 JSON,路径和查询参数都相同。
- 14 种语言的片名和简介,用
language选择。 - 通过
append_to_response获取演员、幕后人员、预告片、关键词、图片和上映日期。 - 已知时提供 IMDb、Kinopoisk、Metacritic、Rotten Tomatoes 和 TMDB 的评分。
- 来自
https:/的海报,无需密钥。/ img.amodb.dev/ t/ p/ {size}/ {file}
可获取的数据
| 你需要 | 调用 | 说明 |
|---|---|---|
| 按片名查找电影 | GET / | 分页,每页最多 20 条结果,边缘缓存 10 分钟。见搜索。 |
| 核心记录 | GET / | 片名、简介、时长、类型、上映日期。见电影。 |
| 演员和幕后人员 | append_ | 字段在演职员页说明。 |
| 预告片 | append_ | 返回带有 key、site 和 type 的 results 数组。 |
| 评分 | append_ | 五个来源,每个为 { value, votes } 或 null。见评分。 |
| OMDb 风格的响应 | GET /omdb/?t=Inception | 响应体字段与 OMDb 相同。见 OMDb 接口。 |
三步开始
- 在定价页选择套餐。套餐只在速率上不同:每分钟 20、40 或 120 个请求。
- 在账户后台创建密钥。密钥是 32 位小写十六进制字符。
- 调用接口,密钥放在
api_key参数或Authorization: Bearer请求头中。见认证。
请求示例
示例按片名找到《盗梦空间》,取第一条结果,再用一次调用读取该电影及其演职员、预告片和评分。总共两次请求。
# 1. find the id
curl -s "https://api.amodb.dev/3/search/movie?query=inception&language=en-US" \
-H "Authorization: Bearer $AMODB_KEY"
# 2. read the movie with extras
curl -s "https://api.amodb.dev/3/movie/27205?language=en-US&append_to_response=credits,videos,ratings" \
-H "Authorization: Bearer $AMODB_KEY"const base = 'https://api.amodb.dev/3';
const headers = { Authorization: `Bearer ${process.env.AMODB_KEY}` };
async function get(path, params) {
const res = await fetch(`${base}${path}?${new URLSearchParams(params)}`, { headers });
if (res.status === 429) {
throw new Error(`Over the limit, retry in ${res.headers.get('Retry-After')} s`);
}
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
return res.json();
}
const found = await get('/search/movie', { query: 'inception', language: 'en-US' });
if (!found.results.length) throw new Error('No match');
const movie = await get(`/movie/${found.results[0].id}`, {
language: 'en-US',
append_to_response: 'credits,videos,ratings',
});
const director = movie.credits.crew.find((c) => c.job === 'Director');
console.log(movie.title, movie.release_date, movie.runtime, director?.name);
console.log('IMDb', movie.ratings.imdb?.value);精简后的响应。只保留了电影记录的部分字段,credits 缩减为一名演员和导演,videos 部分已省略。
{
"genres": [
{
"id": 12,
"name": "Adventure"
},
{
"id": 28,
"name": "Action"
},
{
"id": 80,
"name": "Crime"
}
],
"id": 27205,
"imdb_id": "tt1375666",
"poster_path": "/xlaY2zyzMfkhk0HSC5VUwzoZPU1.jpg",
"release_date": "2010-07-15",
"runtime": 148,
"title": "Inception",
"credits": {
"cast": [
{
"adult": false,
"gender": 2,
"id": 6193,
"known_for_department": "Acting",
"name": "Leonardo DiCaprio",
"original_name": "Leonardo DiCaprio",
"popularity": 9.3213,
"profile_path": "/wo2hJpn04vbtmh0B9utCFdsQhxM.jpg",
"character": "Dom Cobb",
"credit_id": "52fe4534c3a368484e04de03",
"order": 0
}
],
"crew": [
{
"adult": false,
"gender": 2,
"id": 525,
"known_for_department": "Directing",
"name": "Christopher Nolan",
"original_name": "Christopher Nolan",
"popularity": 8.578,
"profile_path": "/xuAIuYSmsUzKlUMBFGVZaWsY3DZ.jpg",
"credit_id": "5e83ac2ee33f830018359a00",
"department": "Directing",
"job": "Director"
}
]
},
"ratings": {
"imdb": {
"value": 8.8,
"votes": 2877173
},
"kinopoisk": {
"value": 8.7,
"votes": null
},
"metacritic": {
"value": 74,
"votes": null
},
"rotten_tomatoes": {
"value": 86,
"votes": null
},
"tmdb": {
"value": 8.373,
"votes": 40457
}
}
}查找电影的方式
请选择与你手头信息相匹配的调用。
| 你手上有 | 调用 | 结果 |
|---|---|---|
| 用户输入的片名 | GET / | 含 id、title、release_date、poster_path 的 results 数组 |
形如 tt0133093 的 IMDb ID | GET / | movie_results 数组 |
形如 603 的数字电影 ID | GET /3/movie/603 | 完整记录 |
| 现有的 OMDb 客户端 | GET /omdb/?i=tt0133093 | 含 Title、Year、Ratings 的 OMDb 响应体 |
请同时保存两个 ID。数字 id 是其他所有调用的键,imdb_id 则用于把你的数据与其他系统关联。查找规则见按外部 ID 查找。
空字段与失败的查找
真实的电影数据总有缺口,所以请为此编写显示代码。没有命中的搜索不是错误:它返回 HTTP 200 和空的 results 数组。未知的 ID 才是错误。
| 情况 | 你看到的内容 | 应对方式 |
|---|---|---|
| 搜索无命中 | 200 和 "results": [] | 显示“无匹配”,不要重试 |
| 未知的电影 ID | 404,status_code 为 34 | 从你的列表中删除该 ID |
| 密钥缺失或错误 | 401,status_code 为 7 | 停止并修正密钥 |
overview 为空 | 空字符串 | 用 language=en-US 再请求一次 |
| 评分未知 | ratings 中为 null | 隐藏该徽章 |
| 没有上映日期 | release_date 为空 | 把该作品排在最后 |
完整的错误列表见错误。
控制在速率限制之内
一次搜索和一次详情调用各算一个请求。每分钟 20 个请求时,相当于每分钟十次片名查询;每分钟 120 个请求时则是六十次。边缘缓存命中同样计数,因为密钥检查和速率限制先于缓存执行。请为重复查询自建缓存,并读取 X-RateLimit-Remaining 了解这一分钟还剩多少。收到 429 时,等待 Retry-After 指定的秒数。各套餐的限制见速率限制。
对比
| 能力 | 自己抓取页面 | 免费层元数据 API | amodb |
|---|---|---|---|
| 响应格式 | 需要自己解析的 HTML | JSON | TMDB v3 结构的 JSON |
| 结构稳定性 | 页面标记变化就会失效 | 由提供方决定 | 路径和字段固定,可能新增字段 |
| 访问条款 | 适用各网站的条款 | 免费层附带使用条款,请查看 | 付费,预付,无免费额度 |
| 速率限制 | 没有可依赖的限制 | 由提供方决定 | 每个密钥每分钟 20、40 或 120 个请求 |
| 多来源评分 | 每个网站一个爬虫 | 各不相同,请查阅文档 | 同一次调用中的 ratings,未知时为 null |
| 语言 | 各页面提供什么就是什么 | 各不相同 | 14 种,用 language 选择 |
| 复用 TMDB v3 和 OMDb 客户端 | 不可以 | 仅当使用相同协议时 | 可以,更换基础 URL |
定价
访问需预付 1、3、6、12 或 24 个月,较长的周期分别享受 0、10、20、30 和 40% 的折扣。不会自动续费,也没有免费额度。所有套餐都能获取全部数据,区别只在速率:每分钟 20、40 或 120 个请求。请在定价页选择一个,几分钟内即可发出第一次调用。