技术博客
十万个为什么 API:列表→详情两接入点串联的全链路设计

十万个为什么 API:列表→详情两接入点串联的全链路设计

作者: 万维易源
2026-09-02
十万个为什么 API列表详情串联全链路设计科普问答免费接口
# 十万个为什么 API:列表→详情两接入点串联的全链路设计 > 接口:十万个为什么(apiCode=1706)· 接入点:列表(1706-1) → 详情(1706-2) · 免费 · 请求方式:POST/GET · 返回格式:JSON · 适用人群:全栈工程师 / 产品经理 · 阅读时间:约 8 分钟 ## 核心要点 - 本接口是「两段式」设计:列表只给 `id`+`title`,详情才给 `content`,二者必须串联使用。 - 推荐把列表结果落库(存 `id` 与 `title`),用户点开某条时再按需调详情,避免一次性拉取全部正文。 - 时序清晰:关键词入参 → 列表拿 id → 用户选择 → 详情取内容 → 前端渲染。 ## Why:为什么是两段式而不是一个接口返回全部 如果列表就把所有正文都返回,一次查询 210 条(示例 `allNum`)的正文会非常臃肿,绝大多数用户只看其中一两条。拆成「列表轻量 + 详情按需」既省流量也契合免费接口的档位限制。理解了这点,你的数据表和点流程才好设计。 ## What:接口速览 | 项 | 列表(1706-1) | 详情(1706-2) | |----|------|------| | 入参 | `keyword`(必填)、`page` | `id`(必填) | | 出参 | `contentlist[{id,title}]` + 分页 | `title`、`content` | | 角色 | 搜索 / 浏览 | 查看单条 | ## How:全链路实现 **步骤 1 — 数据表设计** 只需两张轻量表,或一张带状态字段的表: ```sql -- 问题列表(来自列表接入点) CREATE TABLE why_question ( id VARCHAR(32) PRIMARY KEY, -- 详情接入点的入参 title VARCHAR(255), keyword VARCHAR(64), -- 检索词,便于复用 page INT ); -- 详情内容(懒加载,点开才填) CREATE TABLE why_content ( id VARCHAR(32) PRIMARY KEY, title VARCHAR(255), content TEXT, fetched_at DATETIME ); ``` **步骤 2 — 时序(用户视角)** ``` 用户输入关键词 ──▶ 调列表(1706-1) ──▶ 展示 title 列表 │ │ │ 用户点击某条 │ ▼ └──────────────────────────▶ 调详情(1706-2, id) ──▶ 渲染 content ``` **步骤 3 — 串联代码(Python)** ```python import requests APP_KEY = "YOUR_APPKEY" BASE = "https://route.showapi.com" def search(keyword: str, page: str = "1") -> list: r = requests.post(f"{BASE}/1706-1", data={"keyword": keyword, "page": page}, params={"appKey": APP_KEY}, headers={"content-type": "application/x-www-form-urlencoded"}, timeout=10).json() body = r["showapi_res_body"] if body.get("ret_code") != "0": raise RuntimeError(body.get("remark")) return body["contentlist"] # [{id, title}, ...] def detail(qid: str) -> dict: r = requests.post(f"{BASE}/1706-2", data={"id": qid}, params={"appKey": APP_KEY}, headers={"content-type": "application/x-www-form-urlencoded"}, timeout=10).json() body = r["showapi_res_body"] if body.get("ret_code") != "0": raise RuntimeError(body.get("remark")) return {"title": body["title"], "content": body["content"]} # 用法 for q in search("地球"): print(q["id"], q["title"]) # 用户点开时:detail(q["id"]) ``` ## 返回示例与解析 列表返回 `contentlist` 数组(每项 `id`/`title`),详情返回 `title`/`content`。串联关键点:**用列表的 `id` 作为详情的入参**,两者字段名一致。 ## 进阶 / 边界 - **懒加载而非预拉取**:不要为每条列表结果提前调详情,按需触发,既快又省档位。 - **缓存 id**:同一关键词的列表结果可缓存(见[《免费档位下:用缓存策略节省调用次数》](https://www.showapi.com/guides/why100k-free-tier-cache-1706))。 - **空结果**:关键词太冷门可能 `contentlist` 为空数组,前端应给"没有找到相关问题"提示。 ## FAQ **Q1:列表能直接返回 content 吗?** 不能。列表只返回 `id`+`title`,正文必须通过详情接入点用 `id` 获取。 **Q2:列表的 id 和详情的 id 是同一个吗?** 是同一个。列表 `contentlist[].id` 直接作为详情入参 `id`。 **Q3:可以并发拉多个详情吗?** 可以,但注意免费档位限制,建议按需串行或加缓存,避免集中打满档位。 **Q4:page 不传会怎样?** 列表 `page` 非必填,不传默认第 1 页(示例默认 "1")。 **Q5:用户点了列表里没有的条目怎么办?** 正常不会,因为 id 来自列表返回;若自行拼接 id,需确保 id 真实存在,否则详情返回失败。 ## 相关能力 / 下一步阅读 - [十万个为什么 API 家长辅助教育场景:儿童科学问答小程序集成](https://www.showapi.com/guides/why100k-kids-education-1706) - [十万个为什么 API:如何优雅展示 title 与 content 科普内容?](https://www.showapi.com/guides/why100k-content-display-1706) - [十万个为什么 API 免费档位下:用缓存策略节省调用次数](https://www.showapi.com/guides/why100k-free-tier-cache-1706) - **本系列共 11 篇**:查看[十万个为什么 API 指南总目录](https://www.showapi.com/guides/why100k-guides-1706)