openlibrary
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseopenlibrary — Book Metadata from Open Library
openlibrary — Open Library 图书元数据
Query Open Library's 50M+ record catalog over its public HTTP API: search works
and authors, walk the edition/work/author graph by ISBN or OLID, enumerate
editions, and read community ratings. No API key exists; everything here is a
keyless GET.
通过公共 HTTP API 查询 Open Library 超过 5000 万条记录的目录:搜索作品和作者,按 ISBN 或 OLID 遍历版本、作品和作者关系图,枚举版本并读取社区评分。不需要 API key;这里的所有操作都是免密钥 GET。
Setup
初始化
Nothing to authenticate: the public Open Library API requires no API key for
reads. There is no token, no registration step, no lazy-auth dance.
bash
undefined无需身份验证:公共 Open Library API 的读取操作不需要 API key。无需 token、无需注册,也没有延迟认证的繁琐流程。
bash
undefinedOptional etiquette: identified User-Agent gets ~3x rate budget (~3 req/s vs ~1)
Optional etiquette: identified User-Agent gets ~3x rate budget (~3 req/s vs ~1)
export OL_EMAIL="you@example.com"
Requires Python 3.8+ and `requests` only. `--help` and `--dry-run` work with no
environment at all. Write endpoints exist upstream but require an authenticated
Internet Archive session and are effectively internal — treat this surface as
read-only.
Three hosts matter and they serve different things:
| Host | Serves |
|------|--------|
| `openlibrary.org` | metadata JSON: search, records, ratings |
| `covers.openlibrary.org` | cover images + author photos (separate service) |
| `archive.org` | scan content / bulk dumps (redirect targets) |export OL_EMAIL="you@example.com"
仅需 Python 3.8+ 和 `requests`。`--help` 与 `--dry-run` 在完全没有环境变量的情况下也可运行。上游存在写入端点,但需要经过身份验证的 Internet Archive 会话,实际上属于内部接口——应将此接口视为只读。
有三个重要主机,各自提供不同内容:
| 主机 | 提供 |
|------|--------|
| `openlibrary.org` | 元数据 JSON:搜索、记录、评分 |
| `covers.openlibrary.org` | 封面图片和作者照片(独立服务) |
| `archive.org` | 扫描内容或批量转储(重定向目标) |Essential Commands
核心命令
find books — search
查找书籍——搜索
bash
openlibrary search --query "dune" # relevance order
openlibrary search --query "dune" --sort editions # most editions first
openlibrary search --query "dune" --sort new # newest first
openlibrary search --query "foundation" --lang fr # prefer French editions
openlibrary search --query "dune" --limit 5 --offset 10 # paginate
openlibrary search --query "dune" --json # machine-readableResults carry title, authors, , edition count, and the work
key () that feeds the other commands. The CLI validates
choices client-side because an unknown sort value makes the server return a
plain-text HTTP 500.
first_publish_year/works/OL…W--sortbash
openlibrary search --query "dune" # relevance order
openlibrary search --query "dune" --sort editions # most editions first
openlibrary search --query "dune" --sort new # newest first
openlibrary search --query "foundation" --lang fr # prefer French editions
openlibrary search --query "dune" --limit 5 --offset 10 # paginate
openlibrary search --query "dune" --json # machine-readable结果包含 title、authors、、版本数量,以及可馈入其他命令的 work key()。CLI 会在客户端验证 选项,因为未知排序值会让服务器返回纯文本 HTTP 500。
first_publish_year/works/OL…W--sortfind people who write — author search
查找作者——作者搜索
bash
openlibrary search-authors --query "asimov" # name candidates
openlibrary search-authors --query "le guin" --limit 5
openlibrary search-authors --query "asimov" --json # includes top_work, work_countAuthor docs arrive with bare keys (), unlike book search's path keys.
OL23919Abash
openlibrary search-authors --query "asimov" # name candidates
openlibrary search-authors --query "le guin" --limit 5
openlibrary search-authors --query "asimov" --json # includes top_work, work_count作者文档返回裸键(),不同于书籍搜索返回的路径键。
OL23919Ainspect records — author / work
查看记录——作者或作品
bash
openlibrary author OL23919A # bio, dates, photo URL
openlibrary work OL1168083W # description, subjects, cover URL
openlibrary work OL1168083W --json # full recordKeys may be passed bare () or as paths () — the CLI
normalizes both.
OL23919A/authors/OL23919Abash
openlibrary author OL23919A # bio, dates, photo URL
openlibrary work OL1168083W # description, subjects, cover URL
openlibrary work OL1168083W --json # full record键可以以裸形式()或路径形式()传入——CLI 会将二者标准化。
OL23919A/authors/OL23919Aresolve an ISBN
解析 ISBN
bash
openlibrary isbn 9780451524935 # ISBN-10 or ISBN-13
openlibrary isbn 9780451524935 --json # + resolved edition_key, work_keys, cover_urlUpstream, answers a 302 redirect to the canonical
edition JSON (). The CLI follows it and reports which
edition matched via . If the edition record lacks author names
(some ship ), the CLI recovers them from the linked work.
/isbn/<isbn>.json/books/<OL…M>.jsonedition_keyauthors:nullbash
openlibrary isbn 9780451524935 # ISBN-10 or ISBN-13
openlibrary isbn 9780451524935 --json # + resolved edition_key, work_keys, cover_url在上游, 会对规范 edition JSON()返回 302 redirect。CLI 会跟随该重定向,并通过 报告匹配到的版本。如果版本记录缺少作者姓名(有些记录返回 ),CLI 会从关联的 work 中恢复这些姓名。
/isbn/<isbn>.json/books/<OL…M>.jsonedition_keyauthors:nulllist every edition of a work
列出作品的所有版本
bash
openlibrary editions OL81699W # publisher/date/ISBN per edition
openlibrary editions OL81699W --limit 50 --offset 50 # page through large sets
openlibrary editions OL81699W --json # + next_offset when more existBacks onto ; is computed from the
server's prebuilt next-page link.
/works/<key>/editions.jsonnext_offsetbash
openlibrary editions OL81699W # publisher/date/ISBN per edition
openlibrary editions OL81699W --limit 50 --offset 50 # page through large sets
openlibrary editions OL81699W --json # + next_offset when more exist该命令基于 ; 根据服务器预生成的下一页链接计算。
/works/<key>/editions.jsonnext_offsetread the room — community signals
了解社区动向——社区信号
bash
openlibrary ratings OL45804W # average rating + shelf counts
openlibrary ratings OL45804W --json # full distribution + bookshelvesJoins (, per-star ) with
(, ,
).
/works/<key>/ratings.jsonsummary.averagecounts/works/<key>/bookshelves.jsonwant_to_readcurrently_readingalready_readbash
openlibrary ratings OL45804W # average rating + shelf counts
openlibrary ratings OL45804W --json # full distribution + bookshelves该命令合并 (、逐星 )与 (、、)。
/works/<key>/ratings.jsonsummary.averagecounts/works/<key>/bookshelves.jsonwant_to_readcurrently_readingalready_readGlobal Flags
全局标志
Position-independent; put them before or after the subcommand:
bash
openlibrary --json search --query "dune" # machine output anywhere
openlibrary --dry-run isbn 9780451524935 # preview the exact URL, no network
openlibrary --quiet search --query "dune" # suppress diagnostics| Flag | Effect |
|---|---|
| One JSON object on stdout instead of human text |
| Print the planned request as JSON without executing it |
| Suppress non-essential output |
| Verbose logging |
与位置无关;可放在子命令之前或之后:
bash
openlibrary --json search --query "dune" # machine output anywhere
openlibrary --dry-run isbn 9780451524935 # preview the exact URL, no network
openlibrary --quiet search --query "dune" # suppress diagnostics| 标志 | 效果 |
|---|---|
| 在 stdout 上输出单个 JSON 对象,而不是人类可读文本 |
| 以 JSON 打印计划执行的请求,但不实际执行 |
| 抑制非必要输出 |
| 输出详细日志 |
Multi-Step Pipeline Recipes
多步骤管道示例
ISBN → edition → work → author bio
ISBN → edition → work → 作者简介
The canonical walk across all three key types:
bash
openlibrary isbn 9780451524935 --json | jq -r '.work_keys[0]' # OL1168083W
openlibrary work OL1168083W --json | jq -r '.authors[0]' # bare OL…A key
openlibrary author OL118077A # bio, datesThe CLI keeps this pipeline type-safe: every command that emits an
field under (, ) uses the same shape — an array of bare
OL…A keys — while human output renders comma-separated labels instead. Each hop
uses a different key suffix (M → W → A); see Known Gotchas before hand-assembling
these URLs yourself.
authors--jsonisbnwork这是跨越三种键类型的标准遍历链路:
bash
openlibrary isbn 9780451524935 --json | jq -r '.work_keys[0]' # OL1168083W
openlibrary work OL1168083W --json | jq -r '.authors[0]' # bare OL…A key
openlibrary author OL118077A # bio, datesCLI 让这条管道保持类型安全:在 下输出 字段的每个命令(、)都使用相同结构——由裸 OL…A 键组成的数组——而人类可读输出则改为显示逗号分隔的标签。每一跳使用不同的键后缀(M → W → A);在手动拼接这些 URL 前,请先参阅“常见陷阱”。
--jsonauthorsisbnworkRank a series by community love
按社区喜爱度为系列排名
bash
for w in $(openlibrary search --query 'series:dune' --limit 8 --json | jq -r '.results[].key'); do
openlibrary ratings "${w##*/}" --json \
| jq -c '{work: .key, avg: .average, rated: .ratings_count,
want_to_read: .bookshelves.want_to_read}'
donebash
for w in $(openlibrary search --query 'series:dune' --limit 8 --json | jq -r '.results[].key'); do
openlibrary ratings "${w##*/}" --json \
| jq -c '{work: .key, avg: .average, rated: .ratings_count,
want_to_read: .bookshelves.want_to_read}'
doneFind readable ebooks, then their print editions
查找可读电子书及其纸质版本
bash
openlibrary search --query 'title:"moby dick"' --sort editions --json \
| jq '.results[] | select(.has_fulltext) | {title, key}'
openlibrary editions OL81699W --json | jq '.editions[] | {key, isbn_13}'bash
openlibrary search --query 'title:"moby dick"' --sort editions --json \
| jq '.results[] | select(.has_fulltext) | {title, key}'
openlibrary editions OL81699W --json | jq '.editions[] | {key, isbn_13}'Using --json with jq
将 --json
与 jq
配合使用
--jsonjqbash
openlibrary search --query "voracious" --json | jq '.results[] | {title, first_publish_year}'
openlibrary search-authors --query "butler" --json | jq '.results[0] | {name, key, top_work}'
openlibrary isbn 9780451524935 --json | jq -r '.cover_url' # covers host URL
openlibrary editions OL81699W --json | jq '[.editions[].publish_date]'
openlibrary ratings OL45804W --json | jq '.rating_distribution'bash
openlibrary search --query "voracious" --json | jq '.results[] | {title, first_publish_year}'
openlibrary search-authors --query "butler" --json | jq '.results[0] | {name, key, top_work}'
openlibrary isbn 9780451524935 --json | jq -r '.cover_url' # covers host URL
openlibrary editions OL81699W --json | jq '[.editions[].publish_date]'
openlibrary ratings OL45804W --json | jq '.rating_distribution'Known Gotchas
常见陷阱
- ISBN endpoints answer 302, not JSON — ,
/isbn/<isbn>.json,/lccn/*.jsonredirect to/oclc/*.json. Clients must follow redirects (/books/<OL…M>.json;curl -Ldoes by default) or they parse an HTML redirect page. Directrequestscalls return 200 immediately./books/<OLID>.json - Merged keys return redirect stubs inside HTTP 200 — Open Library is a wiki;
when duplicate works merge, the old key keeps answering 200 with
instead of a 3xx. Detect the stub type in success responses and re-fetch. The bundled CLI does this automatically (and appends
{"type":{"key":"/type/redirect"},"location":"/works/<master>"}to stub locations, since extension-less URLs redirect to HTML pages)..json - Key types are encoded in the suffix — = edition (
OL…M),/books/= work (OL…W),/works/= author (OL…A). Works link to authors double-nested (/authors/); editions nest flat (authors[].author.key) — or shipauthors[].keyentirely, recovering names from the linked work. Requesting a key under the wrong collection yields a 301 reroute.authors:null - Search empties are not errors — malformed queries parse loosely and come
back HTTP 200 with ; conversely a bad
numFound:0enum is a plain-text HTTP 500 and non-integersort=is a FastAPI 422. Branch on bodies, not just status codes.limit - needs
availability— in rawiacalls, requesting/search.jsonsilently returns nothing unlessfields=availabilityis also requested.ia - Covers live on another host — image URLs are always
(or
covers.openlibrary.org/b/id/<cover_id>-{S,M,L}.jpg,/b/isbn/...for author photos). Missing covers return a blank placeholder with HTTP 200 unless you add/a/id/...; non-ID/non-OLID lookups cap at 100 req/IP per 5 min then 403; cover URLs often 302 into archive.org zip shards.?default=false - Rate limits are policy, not headers — no Retry-After/X-Rate-Limit headers
exist. Anonymous ≈1 req/s; a (set
User-Agent: App (email)) raises it to ≈3 req/s. Batch with one search rather than hundreds of lookups; bulk belongs in monthly dumps.OL_EMAIL - Text fields nest objects — older records wrap
{type,value},bio,descriptionasnoteswhile newer ones use plain strings. Handle both; the CLI unwraps centrally.{"type":"/type/text","value":"..."} - OLID ≠ long-term identity — deleted keys can be reassigned to unrelated books, and merged-away keys become redirect stubs. Pair OLIDs with title/ISBN in any cache.
- placement matters for slugged URLs — append
.jsonto the bare key (.json), never after a slug path./authors/OL23919A.json
- ISBN 端点返回 302,而不是 JSON — 、
/isbn/<isbn>.json、/lccn/*.json会重定向到/oclc/*.json。客户端必须跟随重定向(/books/<OL…M>.json;curl -L默认会跟随),否则解析到的将是 HTML 重定向页面。直接调用requests会立即返回 200。/books/<OLID>.json - 合并键会在 HTTP 200 响应中返回重定向存根 — Open Library 是一个 wiki;当重复作品被合并时,旧键仍会返回 HTTP 200,响应内容为 ,而不是 3xx。应在成功响应中检测这种存根类型并重新请求。内置 CLI 会自动处理这一点(并为存根位置追加
{"type":{"key":"/type/redirect"},"location":"/works/<master>"},因为无扩展名 URL 会重定向到 HTML 页面)。.json - 键类型编码在后缀中 — = edition(
OL…M),/books/= work(OL…W),/works/= author(OL…A)。works 通过双层嵌套关联 authors(/authors/);editions 采用扁平嵌套(authors[].author.key)——或者完全不返回authors[].key,此时从关联 work 恢复姓名。在错误的 collection 下请求键会收到 301 reroute。authors:null - 搜索结果为空并不是错误 — 查询格式错误时解析较宽松,服务器会返回 HTTP 200 且 ;反过来,错误的
numFound:0枚举值会返回纯文本 HTTP 500,非整数sort=则会触发 FastAPI 422。应依据响应体分支处理,而不能只看状态码。limit - 需要
availability— 在原始ia调用中,除非同时请求/search.json,否则请求ia会静默返回空值。fields=availability - 封面位于另一台主机 — 图片 URL 始终为 (作者照片则使用
covers.openlibrary.org/b/id/<cover_id>-{S,M,L}.jpg)。缺少封面时,除非添加/a/id/...,否则会返回 HTTP 200 的空白占位图;非 ID、非 OLID 查询每 IP 每 5 分钟最多 100 次,随后返回 403;封面 URL 通常会 302 重定向到 archive.org zip 分片。?default=false - 速率限制是策略而非响应头 — 不存在 Retry-After 或 X-Rate-Limit 响应头。匿名访问约为 1 req/s;设置 (即设置
User-Agent: App (email))后提升至约 3 req/s。批量操作应使用单次搜索,而不是执行数百次查找;批量数据应使用每月转储。OL_EMAIL - 文本字段会嵌套为 对象 — 较旧记录将
{type,value}、bio、description包装为notes,较新记录则使用普通字符串。应同时处理两种形式;CLI 会在统一位置解包。{"type":"/type/text","value":"..."} - OLID ≠ 长期身份标识 — 已删除的键可能被重新分配给无关书籍,被合并掉的键则变成重定向存根。在任何缓存中,都应将 OLID 与 title/ISBN 配对使用。
- 带 slug 的 URL 中 的位置很重要 — 应将
.json追加到裸键末尾(.json),绝不要追加在 slug 路径之后。/authors/OL23919A.json
When to use
适用场景
- Any question about books, authors, or works Open Library's public catalog can answer
- Resolving ISBNs/OLID keys to canonical records and walking edition/work/author graphs
- Finding readable or borrowable scans, cover images, community ratings/shelf counts
- Open Library 公共目录能回答的任何书籍、作者或作品问题
- 将 ISBN/OLID 键解析为规范记录,并遍历版本、作品和作者关系图
- 查找可阅读或可借阅的扫描件、封面图片、社区评分及书架数量
When not to use
不适用场景
Do not use this skill for local library-catalog administration — Koha/Evergreen
ILS configuration, MARC batch processing, patron management — or for licensed
commercial data feeds (ISBNdb, Google Books), citation formatting, or managing
your own Open Library reading account/lists (that requires site login this skill
deliberately does not handle). For movie/TV metadata use tmdb instead.
不要将此 skill 用于本地图书馆目录管理——Koha/Evergreen ILS 配置、MARC 批量处理、读者管理——也不用于授权的商业数据源(ISBNdb、Google Books)、引文格式化,或管理你自己的 Open Library 阅读账户或列表(这些操作需要站点登录,而此 skill 有意不予处理)。对于电影或电视元数据,请改用 tmdb。
Reference Files
参考文件
| File | Topic | Read when |
|---|---|---|
| references/api-overview-and-key-graph.md | Access model, rate-limit etiquette, OLID M/W/A key graph, cross-collection 301s, merge-stub handling, | Assembling record URLs by hand, handling merges/wrong-key errors, or planning request pacing |
| references/search-api-guide.md | | Building precise queries, paginating deep result sets, or debugging empty results |
| references/books-isbn-and-covers.md | Identifier endpoints and their 302 resolution, raw records vs legacy | Working with ISBNs/LCCNs/OCLCs, enumerating editions, or fetching images |
| references/recipes-and-gotchas.md | End-to-end curl/jq pipelines (ISBN→work→author chain, ebook discovery, cover assembly, disambiguation) plus a symptom-indexed gotcha table | Wiring multi-step workflows or diagnosing an unexpected response |
| 文件 | 主题 | 阅读时机 |
|---|---|---|
| references/api-overview-and-key-graph.md | 访问模型、速率限制礼仪、OLID M/W/A 键图、跨 collection 301、合并存根处理、 | 手动组装记录 URL、处理合并或错误键,或规划请求节奏时 |
| references/search-api-guide.md | | 构建精确查询、深层分页,或调试空结果时 |
| references/books-isbn-and-covers.md | 标识符端点及其 302 解析、原始记录与旧版 | 处理 ISBN/LCCN/OCLC、枚举版本或获取图片时 |
| references/recipes-and-gotchas.md | 端到端 curl/jq 管道(ISBN→work→author 链、电子书发现、封面组装、消歧),以及按症状索引的陷阱表 | 连接多步骤工作流或诊断异常响应时 |
Available Scripts
可用脚本
| Script | Purpose | Invocation |
|---|---|---|
| The CLI this skill drives: | |
| Offline pytest/unittest suite covering help, argument errors, dry-run plans, mocked-client logic (redirect stubs, author fallback, editions paging), plus two env-guarded live probes ( | |
| 脚本 | 用途 | 调用方式 |
|---|---|---|
| 此 skill 驱动的 CLI: | |
| 离线 pytest/unittest 测试套件,覆盖帮助信息、参数错误、dry-run 计划、mock client 逻辑(重定向存根、作者回退、版本分页),以及两个受环境变量保护的真实探测( | |
Prerequisites
前置条件
- Python 3.8+ with (stdlib otherwise); invoke as
requestsif not executable directlypython3 scripts/openlibrary ... - No credentials of any kind; optional for rate-limit etiquette
OL_EMAIL - recommended for
jqpost-processing--json
- Python 3.8+ 和 (其余均使用标准库);如果脚本未直接设为可执行文件,请使用
requests调用python3 scripts/openlibrary ... - 无需任何凭据;可选用 遵守速率限制礼仪
OL_EMAIL - 推荐使用 对
jq输出进行后处理--json