技术博客
避坑:三大接入点返回字段大小写不一致,解析代码怎么写才稳

避坑:三大接入点返回字段大小写不一致,解析代码怎么写才稳

作者: 万维易源
2026-09-03
猜一猜谜语API字段大小写解析避坑适配器
# 避坑:三大接入点返回字段大小写不一致,解析代码怎么写才稳 > 接口/接入点:猜一猜谜语 API(151-2 / 151-3 / 151-4) · 免费 · 适用人群:所有需写解析代码的开发者 · 阅读时间:约 5 分钟 ## 核心要点 - 同一接口三个接入点返回字段命名不统一:151-2 用 `Title`/`Answer`(大写),151-4 用 `title`/`answer`(小写),151-3 是 `typeList[id/name]`。 - 根对象命名也不同:151-2 是 `pagebean`,151-4 是 `pb`,151-3 无分页对象。 - 稳的写法:**先判字段存在性再取值**,用一个统一适配器屏蔽差异,别硬编码某个接入点的键名。 ## Why:为什么这篇是避坑必读 照抄 151-2 的 `item.Title` 去解析 151-4,会得到 `undefined`;把 151-3 当谜面列表解析会崩溃。一次写对适配器,后面三个接入点都能复用。 ## What:差异总览 | 接入点 | 谜面键 | 谜底键 | 列表根 | 分页对象 | |--------|--------|--------|--------|---------| | 151-2 | `Title` | `Answer` | `pagebean.contentlist` | `pagebean` | | 151-4 | `title` | `answer` | `pb.contentlist` | `pb` | | 151-3 | (无,仅类型) | (无) | `typeList` | 无 | ## How:统一适配器 ### Python 适配器(兼容三套) ```python def parse_riddle(rb): """返回 list[dict],每项含 title/answer/typeId/typeName(类型查询仅有 id/name)。""" # 151-2:pagebean.contentlist(大写 Title/Answer) if "pagebean" in rb: return [{ "title": i.get("Title"), "answer": i.get("Answer"), "typeId": i.get("typeId"), "typeName": i.get("typeName"), } for i in rb["pagebean"].get("contentlist", [])] # 151-4:pb.contentlist(小写 title/answer) if "pb" in rb: return [{ "title": i.get("title"), "answer": i.get("answer"), "typeId": i.get("typeId"), "typeName": i.get("typeName"), } for i in rb["pb"].get("contentlist", [])] # 151-3:typeList(id/name) if "typeList" in rb: return [{"typeId": t.get("id"), "typeName": t.get("name")} for t in rb["typeList"]] # 兼容 151-2 扁平单条形态(OpenAPI schema 描述) if "Title" in rb or "title" in rb: return [{ "title": rb.get("Title") or rb.get("title"), "answer": rb.get("Answer") or rb.get("answer"), "typeId": rb.get("typeId"), "typeName": rb.get("typeName"), }] return [] ``` ### JavaScript 适配器 ```javascript function parseRiddle(rb) { if (rb.pagebean) return rb.pagebean.contentlist.map(i => ({ title: i.Title, answer: i.Answer, typeId: i.typeId, typeName: i.typeName })); if (rb.pb) return rb.pb.contentlist.map(i => ({ title: i.title, answer: i.answer, typeId: i.typeId, typeName: i.typeName })); if (rb.typeList) return rb.typeList.map(t => ({ typeId: t.id, typeName: t.name })); if (rb.Title || rb.title) return [{ title: rb.Title || rb.title, answer: rb.Answer || rb.answer, typeId: rb.typeId, typeName: rb.typeName }]; return []; } ``` ## 返回示例与解析 调用任一接入点后,先取 `showapi_res_body`,再交给上面的 `parse_riddle`,不要直接 `rb.contentlist`。完整字段见 [返回字段全解](https://www.showapi.com/guides/riddle-response-fields-151)。 ## 进阶/边界 - **别假设键名**:151-2 大写、151-4 小写,统一用 `.get()` / 可选链,避免 `undefined` 抛错。 - **分页字段为字符串**:151-4 的 `allNum`/`allPage` 是字符串,比较前 `int()`。 - **151-2 结构文档矛盾**:返回示例是 `pagebean.contentlist` 数组,字段表/OpenAPI 是扁平单条;适配器已兼容两种形态。 - **151-3 无谜面谜底**:它是类型列表,适配后只有 `typeId`/`typeName`,别当题目用。 ## FAQ **Q1:适配器会不会漏掉扁平形态?** 不会,已包含 151-2 扁平单条(OpenAPI schema 描述)的兼容分支。 **Q2:为什么 151-2 和 151-4 大小写不一样?** 官方各接入点返回定义如此,文档未统一,我们只能在代码层兼容。 **Q3:151-3 解析出来没有 title 正常吗?** 正常,151-3 是类型查询,只返回 `id`/`name`,没有谜面谜底。 **Q4:分页 total 怎么拿?** 151-2 用 `rb.pagebean.allNum`,151-4 用 `rb.pb.allNum`;151-4 是字符串,先转 int。 **Q5:ret_code 在哪?** 在 `showapi_res_body` 内;系统级 `showapi_res_code` 在外层,两者别混。 ## 相关能力 / 下一步阅读 - [猜一猜谜语 API 返回字段全解:三大接入点的 Title/Answer 与分页差异](https://www.showapi.com/guides/riddle-response-fields-151) - [按类型与分页查询谜语:151-4 接入点实战("关键词"真相)](https://www.showapi.com/guides/riddle-search-by-type-151) - [猜一猜谜语 API 类型清单:26 类谜语 typeId 完整对照表](https://www.showapi.com/guides/riddle-typelist-151) - **本系列共 13 篇**:查看[猜一猜谜语 API 指南总目录](https://www.showapi.com/guides/riddle-guides-151)