技术博客
古籍查询 API 返回字段全解:trainslation 拼写坑与每个字段含义

古籍查询 API 返回字段全解:trainslation 拼写坑与每个字段含义

作者: 万维易源
2026-09-03
古籍查询API教程免费接口ShowAPI
# 古籍查询 API 返回字段全解:trainslation 拼写坑与每个字段含义 > 接口:古籍查询(apiCode 1643)· 接入点 1643-3「查询古籍明细」· **免费服务** · 请求方式 POST/GET · 返回 JSON > 适用人群:要正确解析返回、做数据落库的开发者 · 阅读时间:约 6 分钟 ## 核心要点 - 明细返回的核心是一个数组 `ancientBooksInfo[]`,每个元素是一部书的一个「篇章」。 - **译文的 JSON 键名是 `trainslation`(少一个 s)**,不是 `translation`——这是接口真实字段名,OpenAPI 文档也未列出,最易踩坑。 - `annotation`(注释)经常是空数组 `[]`,属正常数据缺失,不要据此判断失败;以 `ret_code == "0"` 为准。 ## Why:为什么值得专门看这篇? 返回的字段名和字面意思不完全对应(译文不是 translation、没有"篇幅"字段、注释常空)。不做字段映射就直接 `data.translation` 会拿到 `undefined`。这篇把每个字段讲清,并给出解析模板。 ## What:返回结构速览 业务数据在 `showapi_res_body` 内: | 层级 | 字段 | 类型 | 含义 | |------|------|------|------| | body | `ret_code` | String | "0" 成功,其他失败 | | body | `remark` | String | 提示信息,如"查询成功!" | | body | `allNum` | Number | 该书的篇章总数(本页口径) | | body | `allPages` | Number | 总页数 | | body | `maxResult` | Number | 每页条数(默认 20) | | body | `currentPage` | Number | 当前页 | | body | `ancientBooksInfo` | Array | 篇章数组,详见下表 | `ancientBooksInfo[]` 每个元素: | 字段 | 类型 | 含义 | 注意事项 | |------|------|------|----------| | `title` | String | 书名 | 如"论语" | | `titleId` | String | 该书 Id | 与 1643-2 返回的 titleId 一致 | | `section` | String | **篇章名**(如"学而篇") | 注意:这是"篇/章"名,不是"篇幅/长度" | | `author` | String | 作者 | 多为"佚名"等古籍署名 | | `original` | Array[String] | 原文,按段落切分 | 与 `trainslation` 按索引一一对应 | | `trainslation` | Array[String] | **译文**,按段落切分 | ⚠️ 键名拼写为 `trainslation`(少 s) | | `annotation` | Array[String] | 注释 | ⚠️ 常为 `[]`,非错误 | | `note` | String | 参考资料说明 | 如来源链接 | | `ancientBookId` | String | 该篇章内部 Id | 区别于 `titleId` | ## How:正确解析(多语言) Python: ```python import requests APPKEY = "YOUR_APPKEY" TITLE_ID = "5b23316f618cd77360b91f0d" body = requests.post( f"https://route.showapi.com/1643-3?appKey={APPKEY}", data={"titleId": TITLE_ID, "page": "1"}, headers={"content-type": "application/x-www-form-urlencoded"}, timeout=10 ).json()["showapi_res_body"] if body.get("ret_code") != "0": raise RuntimeError(body.get("remark")) for ch in body["ancientBooksInfo"]: print("篇章:", ch["section"]) for i, para in enumerate(ch["original"]): translation = ch["trainslation"][i] if i < len(ch["trainslation"]) else "" print(f"原文[{i}]:", para) print(f"译文[{i}]:", translation) # 注释可能为空,先判断再处理 notes = ch.get("annotation") or [] if notes: print("注释:", notes) ``` cURL(先看原始返回,确认键名): ```bash curl -X POST "https://route.showapi.com/1643-3?appKey=YOUR_APPKEY" \ -H "content-type: application/x-www-form-urlencoded" \ -d "titleId=5b23316f618cd77360b91f0d&page=1" | python -m json.tool ``` Node.js(fetch): ```javascript const APPKEY = "YOUR_APPKEY"; const TITLE_ID = "5b23316f618cd77360b91f0d"; const body = (await (await fetch(`https://route.showapi.com/1643-3?appKey=${APPKEY}`, { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ titleId: TITLE_ID, page: "1" }) })).json()).showapi_res_body; if (body.ret_code !== "0") throw new Error(body.remark); for (const ch of body.ancientBooksInfo) { ch.original.forEach((para, i) => { const translation = ch.trainslation[i] || ""; // 键名 trainslation console.log(`原文[${i}]:`, para, "| 译文:", translation); }); } ``` ## 真实返回示例(节选) ```json { "showapi_res_body": { "ret_code": "0", "remark": "查询成功!", "ancientBooksInfo": [ { "title": "论语", "titleId": "5b23316f618cd77360b91f0d", "section": "学而篇", "author": "佚名", "original": ["子曰:“学而时习之,不亦说乎?……”"], "trainslation": ["孔子说:“学了又时常温习和练习,不是很愉快吗?……”"], "annotation": [], "note": "参考资料: 1、 佚名.论语百科.http://lunyu.baike.com/article-29298.html", "ancientBookId": "5b286b7e618c454cc40b5997" } ], "maxResult": 20, "allNum": 20, "allPages": 1, "currentPage": 1 } } ``` ## 进阶 / 边界 - **对照阅读的最佳实践**:`original` 与 `trainslation` 都是数组且按段落对齐,用同一索引 `i` 配对展示最稳;但个别篇章两者长度可能不一致,配对前用 `min(len(original), len(trainslation))` 或逐个判空兜底。 - **没有"篇幅"字段**:产品描述里的"篇幅"在返回中并无独立字段,对应到 `section`(篇章名)。不要去找 `length`/`size` 之类字段。 - **`annotation` 为空是正常的**:很多古籍/篇章没有注释数据,返回 `[]`,与调用成功与否无关。 - **`note` 是参考资料**:通常是外部来源链接,展示时可做来源标注。 ## FAQ **Q1:为什么 `data.translation` 取不到值?** A:真实键名是 `trainslation`(少一个 s)。改成 `data.trainslation`。 **Q2:OpenAPI 文档里没有 trainslation 字段?** A:对,接口实际返回包含 `trainslation`,但官方 OpenAPI schema 未列它。以接口实测返回为准。 **Q3:original 和 trainslation 长度不一样怎么办?** A:按索引配对时做长度兜底(取较小者,缺的一侧留空),避免越界。 ## 相关能力 / 下一步阅读 - [古籍查询 API:按 titleId 获取古籍明细(原文 / 译文 / 注释)](https://www.showapi.com/guides/ancient-books-detail-1643) - [古籍查询 API 分页机制:page / maxResult / allPages 怎么用](https://www.showapi.com/guides/ancient-books-pagination-1643) - [古籍查询 API 常见问题与避坑指南(trainslation 拼写、注释为空、分页)](https://www.showapi.com/guides/ancient-books-faq-1643) - **本系列共 10 篇**:查看[古籍查询 API 指南总目录](https://www.showapi.com/guides/ancient-books-guides-1643)