唐诗宋词元曲查询:从「朝代」到「诗人」到「诗词」三步全链路串联
# 唐诗宋词元曲查询:从「朝代」到「诗人」到「诗词」三步全链路串联
> 接口:唐诗宋词元曲等诗词查询(apiCode=1620)· 免费 · 请求方式 POST/GET · 返回 JSON · 适用:产品经理、全栈工程师、教育内容运营 · 阅读约 7 分钟
## 核心要点
- 三个接入点是**顺承关系**:朝代(1620-3)→ 诗人(1620-4)→ 诗词(1620-5),靠 ID 接力
- 关键接力字段:`dynastyId`(1620-3 出)→ 1620-4 入;`poetId`(1620-4 出)→ 1620-5 入
- 一条链路即可支撑「选朝代 → 看诗人 → 读诗词原文译文注释」的完整产品体验
## Why:三个接口单独用都很单薄,串起来才是产品
单独查朝代列表,只是一串名字;单独查诗人,得先知道 ID;单独查诗词,又要先知道 `poetId` 或精确 `title`。真正有用的体验是:**用户点一个朝代,系统自动列出该朝代诗人,再点诗人就看到他的作品和赏析**。这就是三个接入点的设计意图——用 ID 串成链路。
## What:链路与接口速览
| 步骤 | 接入点 | 关键入参 | 关键出参(接力字段) |
|------|--------|---------|---------------------|
| 1 | 1620-3 查询朝代列表 | 无 | `dynastyId` |
| 2 | 1620-4 人名或朝代查询诗人 | `dynastyId`(或 `poet`) | `poetId` |
| 3 | 1620-5 名称查询诗词列表 | `poetId`(或 `title`) | `poemInfo` / `contentlist` |
| 项目 | 说明 |
|------|------|
| 接口编码 | 1620 |
| 返回格式 | JSON,业务数据在 `showapi_res_body` |
| 鉴权 | `appKey` 作为查询参数 |
| 计费 | 免费(有使用档次限制) |
## How:三步串联实现
### 步骤 1 · 取朝代列表,拿到 dynastyId
调用 1620-3,渲染朝代下拉/列表;用户选中某朝代时,记录其 `dynastyId`(如「宋代」= `5b1de348cbf6a77b365977e5`)。
### 步骤 2 · 用 dynastyId 查该朝代诗人
调用 1620-4,传 `dynastyId`,得到 `poetInfo`;用户点某诗人时记录 `poetId`。
### 步骤 3 · 用 poetId 查诗词详情
调用 1620-5,传 `poetId`,得到 `poemInfo`,遍历 `contentlist` 渲染原文/译文/注释。
**Python 串联示例**
```python
import requests
APP_KEY = "YOUR_APPKEY"
H = {"content-type": "application/x-www-form-urlencoded"}
def call(path, **params):
r = requests.post(f"https://route.showapi.com/{path}",
params={"appKey": APP_KEY, **params}, headers=H, timeout=10)
body = r.json().get("showapi_res_body", {})
if body.get("ret_code") != "0":
raise RuntimeError(body.get("remark"))
return body
# 步骤1:朝代
dyn = call("1620-3")["dynastyInfo"]
song_id = next(d["dynastyId"] for d in dyn if d["dynasty"] == "宋代")
# 步骤2:该朝代诗人
poets = call("1620-4", dynastyId=song_id, page=1)["poetInfo"]
su_shi = next(p for p in poets if p["poet"] == "苏轼")
print("苏轼 poetId:", su_shi["poetId"], "| 简介:", su_shi["biography"][:30], "...")
# 步骤3:苏轼的诗词
poems = call("1620-5", poetId=su_shi["poetId"], page=1)["poemInfo"]
for poem in poems:
for seg in poem["contentlist"]:
print(poem["title"], "→", seg["original"][:20], "...")
```
**时序说明**
```
用户选「宋代」
└─(dynastyId)→ 1620-4 返回诗人列表
用户选「苏轼」(poetId)
└─(poetId)→ 1620-5 返回 poemInfo → contentlist(原文/译文/注释)
```
**cURL(步骤 2 示例)**
```bash
curl -X POST "https://route.showapi.com/1620-4?appKey=YOUR_APPKEY" \
-H "content-type: application/x-www-form-urlencoded" \
-d "dynastyId=5b1de348cbf6a77b365977e5&page=1"
```
**Node.js(fetch,步骤 3 示例)**
```javascript
const APP_KEY = "YOUR_APPKEY";
const body = await (await fetch(
`https://route.showapi.com/1620-5?appKey=${APP_KEY}`,
{ method: "POST", headers: { "content-type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({ poetId: "5b1e3644cbf69480cb8e81b7", page: 1 }) }
)).json();
const list = body.showapi_res_body?.poemInfo || [];
list.forEach(p => p.contentlist.forEach(s => console.log(p.title, s.original)));
```
## 返回示例与解析
1620-4 返回片段(苏轼):
```json
{
"showapi_res_body": {
"ret_code": "0",
"remark": "查询成功!",
"poetInfo": [
{
"poet": "苏轼",
"dynastyId": "5b1de348cbf6a77b365977e5",
"dynasty": "宋代",
"poetId": "5b1e3644cbf69480cb8e81b7",
"biography": "苏轼(1037-1101),北宋文学家……"
}
],
"allPages": 1, "currentPage": 1, "allNum": 1, "maxResult": 20
}
}
```
`poetId` 即步骤 3 的入参。注意 1620-4 的 `biography` 是完整生平简介,可直接用于诗人详情页。
## 进阶 / 边界
- **也可「跳步」**:1620-4 支持直接传 `poet`(诗人名)而不依赖 `dynastyId`;1620-5 支持直接传 `title`(精确)而不依赖 `poetId`。链路是推荐用法,不是强制顺序。
- **ID 稳定性**:`dynastyId` / `poetId` / `poemId` 由数据源分配,建议以 ID 而非名称做关联键,避免因异体字/别称导致匹配失败。
- **缓存接力**:朝代列表几乎不变,可长期缓存;诗人列表与诗词列表可按 `dynastyId` / `poetId` 做键缓存(详见《免费也有档次限制,如何用本地缓存避免触发限流?》)。
- **空结果兜底**:某朝代可能没有匹配诗人或诗词,前端需提示「暂无数据」而非崩溃。
## FAQ
**Q1:能不能不查朝代,直接按诗人名查诗词?**
可以。1620-4 直接传 `poet=苏轼` 拿到 `poetId`,再传 1620-5 的 `poetId` 查诗词。朝代只是可选入口之一。
**Q2:dynastyId 和 poetId 能从别处写死吗?**
不建议写死。这些值由数据源分配,应以实时接口返回的 ID 为准;若需固定映射,先调一次接口建立「名称→ID」映射表并定期刷新。
**Q3:三步会不会很慢,要发三次请求?**
三次请求是顺序的(后一步依赖前一步的 ID),但单次接口本身耗时低。可对前两步结果做缓存(朝代几乎不变、热门诗人可预热),实际用户交互中通常只发最后一步。
**Q4:能否一次拿到某朝代全部诗人的全部诗词?**
接口本身不提供「连表」查询,需由你自己的代码循环:遍历诗人列表 → 逐个查诗词 → 聚合。注意分页与限流(每页 `maxResult=20`)。
## 相关能力 / 下一步阅读
- [唐诗宋词元曲查询返回结构全解:ret_code、dynastyInfo、poemInfo 一文读懂](https://www.showapi.com/guides/poem-response-fields-1620) — 字段细节速查
- [唐诗宋词元曲查询:title 名称查询为什么不支持模糊匹配?正确用法与避坑](https://www.showapi.com/guides/poem-title-exact-1620) — 步骤 3 用 title 时的约束
- **本系列共 12 篇**:查看[唐诗宋词元曲查询指南总目录](https://www.showapi.com/guides/poem-guides-1620)