技术博客
绕口令与谜语查询:分页遍历指南(用 page/allPages 拉取全部数据)

绕口令与谜语查询:分页遍历指南(用 page/allPages 拉取全部数据)

作者: 万维易源
2026-09-03
分页遍历page参数allPages重试指数退避
# 绕口令与谜语查询:分页遍历指南(用 page/allPages 拉取全部数据) **接口**:绕口令与谜语查询(apiCode=1623)· 接入点 1623-1 / 1623-2|**是否免费**:免费(含使用档次限制)|**请求方式**:POST/GET|**返回格式**:JSON|**适用人群**:需要全量语料的开发者、运营|**阅读时间**:约 6 分钟 ## 核心要点 - 翻页靠 `page` 参数,从 `1` 循环到 `showapi_res_body.allPages`;`allNum` 是总数可用于校验。 - 免费接口有档次限制,**逐页循环会快速消耗额度**,务必配合本地缓存(见[本地缓存策略](https://www.showapi.com/guides/tongue-riddle-cache-tier-1623))。 - 生产级写法要带「失败重试 + 指数退避 + 单页上限控制」,不要裸循环。 ## Why:什么时候需要翻页? 做离线语料库、批量生成卡片、全量备份时,单页约 10 条不够用。用分页把全部绕口令/谜语拉下来,落库后日常查询走本地,不再反复打接口。 ## What:分页四字段回顾 | 字段 | 含义 | |------|------| | `page` | 请求参数,页码,默认 1,字符串类型 | | `currentPage` | 当前返回的页码 | | `allPages` | 总页数,循环终点 | | `allNum` | 总条数,可用于校验累计条数 | ## How:自动翻页 + 重试(Python) ```python import time import requests APP_KEY = "YOUR_APPKEY" URL = "https://route.showapi.com/1623-1" # 谜语改用 1623-2,timeout 改 15 TIMEOUT = 5 def fetch_page(keyword: str, page: int, max_retry: int = 3) -> dict: for attempt in range(max_retry): try: resp = requests.post( URL, params={"appKey": APP_KEY}, data={"title": keyword, "page": str(page)}, timeout=TIMEOUT, ) body = resp.json()["showapi_res_body"] if body["ret_code"] != "0": raise RuntimeError(body.get("showapi_res_error")) return body except Exception as e: if attempt == max_retry - 1: raise time.sleep(2 ** attempt) # 指数退避:1s, 2s return {} def collect_all(keyword: str = "") -> list: results, page = [], 1 while True: body = fetch_page(keyword, page) results.extend(body.get("contentlist", [])) total_pages = int(body.get("allPages", "1")) if page >= total_pages: break page += 1 return results all_items = collect_all("") # 空关键词拉全部绕口令 print("累计条数:", len(all_items), "接口总条数:", fetch_page("", 1).get("allNum")) ``` **cURL(手动翻第 2 页)** ```bash curl -X POST "https://route.showapi.com/1623-1?appKey=YOUR_APPKEY" \ -H "content-type: application/x-www-form-urlencoded" \ -d "title=&page=2" ``` **Node.js(fetch,带超时与重试)** ```javascript const APP_KEY = "YOUR_APPKEY"; const URL = `https://route.showapi.com/1623-1?appKey=${APP_KEY}`; const TIMEOUT = 5000; async function fetchPage(keyword, page, maxRetry = 3) { for (let attempt = 0; attempt < maxRetry; attempt++) { try { const body = new URLSearchParams({ title: keyword, page: String(page) }); const resp = await fetch(URL, { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded" }, body, signal: AbortSignal.timeout(TIMEOUT), }); const data = await resp.json(); if (data.showapi_res_body.ret_code !== "0") throw new Error(data.showapi_res_error); return data.showapi_res_body; } catch (e) { if (attempt === maxRetry - 1) throw e; await new Promise((r) => setTimeout(r, 2 ** attempt * 1000)); } } } async function collectAll(keyword = "") { const out = []; let page = 1; while (true) { const body = await fetchPage(keyword, page); out.push(...body.contentlist); if (page >= Number(body.allPages)) break; page++; } return out; } ``` ## 返回示例与解析 单页返回结构见[返回字段全解](https://www.showapi.com/guides/tongue-riddle-response-fields-1623);遍历时关注 `allPages` 作循环终点、`allNum` 作总数校验。 ## 进阶 / 边界 - **免费档位是硬约束**:逐页循环对免费接口消耗很快,拉全量建议低频执行(如每日一次)并落库复用。 - 两接入点独立分页:绕口令的 `allPages` 与谜语的 `allPages` 互不影响,分别遍历。 - 单页上限 `maxResult=1000`,但实际返回约 10 条,不要以为一次能拿 1000 条。 ## FAQ **Q1:page 传数字还是字符串?** A:文档示例为字符串(如 `"1"`),建议传字符串,避免个别网关类型转换问题。 **Q2:拉到一半失败了怎么办?** A:用「已落库的最后页码」做断点续传,从失败页重新 fetch,配合上面的重试逻辑。 **Q3:免费接口翻很多页会被限流吗?** A:会。文档明确有使用档次限制,全量遍历请控制频率并缓存结果,详见[本地缓存策略](https://www.showapi.com/guides/tongue-riddle-cache-tier-1623)。 **Q4:allPages 很大(如 100)正常吗?** A:正常,表示内容库总量大;逐页拉取耗时与额度消耗都会随页数线性增长。 **Q5:能并发翻页加速吗?** A:可,但免费接口档位有限,并发更易触发限制;建议串行 + 退避,或确认额度后再并发。 ## 下一步阅读 - [绕口令与谜语查询:绕口令关键词检索实战](https://www.showapi.com/guides/tongue-riddle-twister-query-1623) - [绕口令与谜语查询:谜语关键词检索实战](https://www.showapi.com/guides/tongue-riddle-riddle-query-1623) - [绕口令与谜语查询:免费档位下的调用纪律与本地缓存策略](https://www.showapi.com/guides/tongue-riddle-cache-tier-1623) - **本系列共 12 篇**:查看[绕口令与谜语查询指南总目录](https://www.showapi.com/guides/tongue-riddle-guides-1623)