技术博客
绕口令与谜语查询:免费档位下的调用纪律与本地缓存策略

绕口令与谜语查询:免费档位下的调用纪律与本地缓存策略

作者: 万维易源
2026-09-03
免费档位本地缓存Redis调用纪律防滥用
# 绕口令与谜语查询:免费档位下的调用纪律与本地缓存策略 **接口**:绕口令与谜语查询(apiCode=1623)· 接入点 1623-1 / 1623-2|**是否免费**:免费(含使用档次限制)|**返回格式**:JSON|**适用人群**:已接入、准备上生产的开发者|**阅读时间**:约 6 分钟 ## 核心要点 - 本接口是**免费服务但设有使用档次限制**(防滥用),文档未给出具体档位数字——额度以[官方档位说明](https://www.showapi.com/free-api)为准,本文不编造。 - 缓存是守住免费额度、避免被限流的最直接手段:以「接入点 + 关键词 + page」为 key,命中即返回、不调接口。 - 缓存 TTL 建议按「内容更新频率」设定;文档标注「数据持续更新中」,可设较短 TTL(如数小时~1 天)兼顾新鲜度与省量。 ## Why:免费 ≠ 无限,省着用才长久 免费接口的档次限制是为了防止滥用。你的每一次重复查询(同一关键词翻同一页、全班同时刷新、前端轮询)都在消耗额度。用本地缓存把「重复请求」挡在本地,既快又省,还能在接口抖动时兜底。 ## What:缓存什么、以什么为 key | 维度 | 建议 | |------|------| | 缓存 key | `接入点 + 关键词 + page`(如 `1623-1:扁担:1`) | | 缓存 value | 整个 `contentlist`(或整页 `showapi_res_body`) | | TTL | 数小时~1 天;内容更新频繁可更短 | | 落库位置 | 服务端内存/Redis,或前端静态 JSON(活动场景) | ## How:带缓存的查询(Python + 简单内存/文件缓存) ```python import json, time, requests APP_KEY = "YOUR_APPKEY" CACHE_FILE = "tongue_riddle_cache.json" TTL = 3600 * 6 # 6 小时 _cache = {} def load_cache(): try: with open(CACHE_FILE, "r", encoding="utf-8") as f: return json.load(f) except FileNotFoundError: return {} def save_cache(c): with open(CACHE_FILE, "w", encoding="utf-8") as f: json.dump(c, f, ensure_ascii=False) def cached_query(point: str, keyword: str, page: int = 1): global _cache _cache = load_cache() key = f"{point}:{keyword}:{page}" now = time.time() hit = _cache.get(key) if hit and now - hit["ts"] < TTL: return hit["body"] # 命中,不调接口 url = f"https://route.showapi.com/{point}" timeout = 5 if point == "1623-1" else 15 resp = requests.post( url, params={"appKey": APP_KEY}, data={"title" if point == "1623-1" else "question": keyword, "page": str(page)}, timeout=timeout, ) body = resp.json()["showapi_res_body"] _cache[key] = {"ts": now, "body": body} save_cache(_cache) return body ``` **Node.js(fetch + Map 内存缓存)** ```javascript const APP_KEY = "YOUR_APPKEY"; const TTL = 6 * 3600 * 1000; const cache = new Map(); async function cachedQuery(point, keyword, page = 1) { const key = `${point}:${keyword}:${page}`; const hit = cache.get(key); if (hit && Date.now() - hit.ts < TTL) return hit.body; const url = `https://route.showapi.com/${point}?appKey=${APP_KEY}`; const param = point === "1623-1" ? "title" : "question"; const body = new URLSearchParams({ [param]: keyword, page: String(page) }); const resp = await fetch(url, { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded" }, body, signal: AbortSignal.timeout(point === "1623-1" ? 5000 : 15000), }); const resBody = (await resp.json()).showapi_res_body; cache.set(key, { ts: Date.now(), body: resBody }); return resBody; } ``` ## 返回示例与解析 缓存命中时直接复用历史 `showapi_res_body`,结构同[返回字段全解](https://www.showapi.com/guides/tongue-riddle-response-fields-1623);未命中才真正发起请求。 ## 进阶 / 边界 - **空结果也缓存**:无匹配的 `contentlist` 为空仍是有效响应,可缓存避免反复空查(但 TTL 设短些,内容可能更新)。 - **TTL 取舍**:文档说「数据持续更新中」,TTL 过长会拿到旧内容;按业务容忍度设 1 小时~1 天。 - **服务端 vs 前端**:服务端 Redis 缓存对全用户生效、最省量;纯前端缓存只省本机,适合活动/离线场景。 - **防滥用另一面**:前端侧限流见[前端限流与防滥用](https://www.showapi.com/guides/tongue-riddle-frontend-throttle-1623)。 ## FAQ **Q1:免费额度到底有多少?** A:文档仅说明「免费 + 使用档次限制(防滥用)」,未给具体数字;以[官方档位说明](https://www.showapi.com/free-api)为准,本文不编造。 **Q2:缓存会让内容变旧吗?** A:会,TTL 越长越旧;文档称数据持续更新,建议 TTL 控制在数小时~1 天。 **Q3:缓存 key 要包含 page 吗?** A:要。不同页返回不同内容,key 必须含「接入点 + 关键词 + page」,否则串数据。 **Q4:被限流了怎么恢复?** A:以降低频率 + 提高缓存命中为主;具体恢复规则以官方档位说明为准。 **Q5:能用 CDN/网关层缓存吗?** A:可以,GET 形式且参数固定的请求适合边缘缓存;注意 AppKey 不要进公共缓存 key 暴露。 ## 下一步阅读 - [绕口令与谜语查询:错误处理与 ret_code 排查](https://www.showapi.com/guides/tongue-riddle-error-handling-1623) - [绕口令与谜语查询:分页遍历指南](https://www.showapi.com/guides/tongue-riddle-pagination-1623) - [绕口令与谜语查询:前端限流与防滥用实践](https://www.showapi.com/guides/tongue-riddle-frontend-throttle-1623) - **本系列共 12 篇**:查看[绕口令与谜语查询指南总目录](https://www.showapi.com/guides/tongue-riddle-guides-1623)