唐诗宋词元曲查询:page 与 maxResult=20 分页翻页拉取全部诗词
# 唐诗宋词元曲查询:page 与 maxResult=20 分页翻页拉取全部诗词
> 接口:唐诗宋词元曲等诗词查询(apiCode=1620)· 接入点 1620-4 / 1620-5 · 免费 · 返回 JSON · 适用:需批量拉取数据的开发者 · 阅读约 6 分钟
## 核心要点
- 列表类接入点(1620-4、1620-5)返回分页四件套:`allPages` / `currentPage` / `allNum` / `maxResult`
- `maxResult` 为每页条数(文档示例 20),由服务端控制,**调用方不能改**,只能用 `page` 翻页
- 翻页终止条件:`currentPage >= allPages`;循环时以 `allPages` 为上限最稳
## Why:想拉「苏轼全部 258 首」不能一次拿到
热门诗人的作品很多(苏轼示例 `allNum=258`、`allPages=13`)。接口每页只返回 `maxResult`(20)条,不会一次给全。要本地建索引或做「全部作品」列表,就得翻页把 13 页都取回来。本篇讲清分页字段与稳健翻页写法。
## What:分页字段与接口速览
| 项目 | 说明 |
|------|------|
| 接入点 | 1620-4 人名或朝代查询诗人、1620-5 名称查询诗词列表 |
| 分页入参 | `page`(页码,默认 1) |
| 分页出参 | `allPages`(总页)、`currentPage`(当前页)、`allNum`(总条数)、`maxResult`(每页条数) |
| 返回格式 | JSON,业务数据在 `showapi_res_body` |
| 计费 | 免费(有使用档次限制,翻页多页会消耗档位,注意缓存) |
## How:稳健翻页拉全量
### 步骤 1 · 先取第一页,读出 allPages
### 步骤 2 · 循环翻页直到 allPages
**Python(requests,翻完苏轼全部诗词)**
```python
import requests, time
APP_KEY = "YOUR_APPKEY"
H = {"content-type": "application/x-www-form-urlencoded"}
URL = "https://route.showapi.com/1620-5"
def fetch_page(poet_id, page):
r = requests.post(URL, params={"appKey": APP_KEY, "poetId": poet_id, "page": page},
headers=H, timeout=10)
body = r.json().get("showapi_res_body", {})
if body.get("ret_code") != "0":
raise RuntimeError(body.get("remark"))
return body
all_poems = []
first = fetch_page("5b1e3644cbf69480cb8e81b7", 1)
all_poems.extend(first["poemInfo"])
total_pages = first["allPages"]
for p in range(2, total_pages + 1):
body = fetch_page("5b1e3644cbf69480cb8e81b7", p)
all_poems.extend(body["poemInfo"])
time.sleep(0.2) # 翻页间稍作间隔,避免触发限流
print("共拉取", len(all_poems), "首,allNum=", first["allNum"])
```
**cURL(第 2 页示例)**
```bash
curl -X POST "https://route.showapi.com/1620-5?appKey=YOUR_APPKEY" \
-H "content-type: application/x-www-form-urlencoded" \
-d "poetId=5b1e3644cbf69480cb8e81b7&page=2"
```
**Node.js(fetch)**
```javascript
const APP_KEY = "YOUR_APPKEY";
const H = { "content-type": "application/x-www-form-urlencoded" };
let page = 1, all = [], total;
do {
const body = (await (await fetch(`https://route.showapi.com/1620-5?appKey=${APP_KEY}`, {
method: "POST", headers: H,
body: new URLSearchParams({ poetId: "5b1e3644cbf69480cb8e81b7", page }),
})).json()).showapi_res_body;
if (body.ret_code !== "0") throw new Error(body.remark);
all.push(...body.poemInfo);
total = body.allPages;
} while (++page <= total);
console.log("共", all.length, "首");
```
## 返回示例与解析
```json
{
"showapi_res_body": {
"ret_code": "0",
"poemInfo": [ { "title": "前赤壁赋", "poet": "苏轼", "dynasty": "宋代", "contentlist": [ { "original": "…", "translation": "…", "annotation": "…" } ] } ],
"maxResult": 20,
"allNum": 258,
"allPages": 13,
"currentPage": 1
}
}
```
| 字段 | 含义 | 用法 |
|------|------|------|
| `maxResult` | 每页条数(示例 20) | 仅供参考,不能由调用方设置 |
| `allNum` | 总条数(258) | 校验拉取是否完整 |
| `allPages` | 总页数(13) | 翻页循环上限 |
| `currentPage` | 当前页 | 调试/断点续拉用 |
## 进阶 / 边界
- **以 allPages 为循环上限**:比算 `ceil(allNum/maxResult)` 更稳,直接信任服务端给出的总页数。
- **翻页间隔**:连续翻多页会累积请求量,免费档位有限,建议每页间 `sleep` 一小段,并对结果做缓存(见《免费也有档次限制,如何用本地缓存避免触发限流?》)。
- **断点续拉**:大批量可记录已拉 `currentPage`,失败从断点重拉,避免重复消耗档位。
- **`maxResult` 不可调**:文档未提供「每页条数」参数,无法一次拉超过 20 条/页。
## FAQ
**Q1:能不能一次拉 100 条,少翻几页?**
不能。每页由服务端固定为 `maxResult`(示例 20),没有可调参数,只能靠 `page` 逐页拉。
**Q2:翻到最后一页只剩几条,会报错吗?**
不会。最后一页不足 `maxResult` 条时正常返回,`allPages` 已含该页,循环到 `allPages` 即止。
**Q3:拉全量会不会很快耗尽免费档位?**
会。258 首需 13 页请求,且同一诗人数据相对稳定。强烈建议首次拉全后本地持久化,后续增量/按需查询,不要每次都翻全量。
**Q4:allNum 和 len(poemInfo 累计) 不一致怎么办?**
说明中途有页缺失或限流打断。以 `allNum` 为基准校验;若不一致,从断点页重拉补齐。
## 相关能力 / 下一步阅读
- [唐诗宋词元曲查询:免费也有档次限制,如何用本地缓存避免触发限流?](https://www.showapi.com/guides/poem-rate-limit-cache-1620) — 翻页拉的缓存与限流策略
- [唐诗宋词元曲查询:title 名称查询为什么不支持模糊查询?正确用法与避坑](https://www.showapi.com/guides/poem-title-exact-1620) — 翻页替代模糊搜索
- **本系列共 12 篇**:查看[唐诗宋词元曲查询指南总目录](https://www.showapi.com/guides/poem-guides-1620)