免费接口也要省:网络搜索热词排行缓存策略与更新频率设计
# 免费接口也要省:网络搜索热词排行缓存策略与更新频率设计
> 接口:网络搜索热词排行(apiCode=313) · 免费服务 · 返回格式 JSON · 适用人群:中高级开发者、架构师 · 阅读时间:约 7 分钟
## 核心要点
- 免费 ≠ 无限调用。热搜数据天然有时效,合理缓存能提升体验、规避潜在限流。
- 推荐按 `tab`(+ 可选 `category`/`country`)做缓存 key,TTL 设 15~60 分钟。
- 缓存未命中才回源接口;命中直接返回,前端无感。
## Why:免费接口为什么还要谈缓存
"免费"只代表不计费,不代表没有频率约束(文档未公开 QPS/限流,实际以平台为准)。如果你的看板、聚合服务每次请求都直连接口,流量一大就可能被限。热搜变化慢,缓存半小时几乎不影响时效性,却能大幅减少对接口的依赖。
## What:缓存设计要素
| 要素 | 建议 |
|------|------|
| 缓存 key | `hotword:{tab}` 或 `hotword:{tab}:{category}:{country}` |
| 存储 | Redis(生产)/ 文件(演示) |
| TTL | 900~3600 秒(15~60 分钟) |
| 回源条件 | key 不存在或已过期 |
## How:生产级缓存写法(Redis)
```python
import requests, redis
APP_KEY = "YOUR_APPKEY"
r = redis.Redis(host="localhost", port=6379, db=0, decode_responses=True)
TTL = 1800 # 30 分钟
def get_hotwords_cached(tab, category=None, country=None):
key = f"hotword:{tab}:{category or ''}:{country or ''}"
cached = r.get(key)
if cached:
return json.loads(cached)
# 回源
resp = requests.post(
"https://route.showapi.com/313-2",
params={"appKey": APP_KEY},
data={"tab": tab, **({"category": category} if category else {}),
**({"country": country} if country else {})},
headers={"content-type": "application/x-www-form-urlencoded"}, timeout=10,
).json()
body = resp.get("showapi_res_body", {})
if str(body.get("ret_code")) != "0":
raise RuntimeError(f"失败: {body.get('ret_code')}")
data = body.get("list", [])
r.setex(key, TTL, json.dumps(data, ensure_ascii=False))
return data
```
### 重试与降级
```python
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
session = requests.Session()
retry = Retry(total=3, backoff_factor=0.5,
status_forcelist=[429, 500, 502, 503, 504])
session.mount("https://", HTTPAdapter(max_retries=retry))
```
`429` 等限流状态码走指数退避;缓存命中时即使接口临时不可用也能用旧数据兜底。
## 返回示例与解析
缓存内容是 313-2 的 `list` 数组(结构见[返回字段全解篇](https://www.showapi.com/guides/hotword-response-fields-313)),序列化后存入 Redis。
## 进阶 / 边界
- **TTL 取多少**:热搜以"小时级"变化,15~60 分钟 TTL 在时效与调用量间较平衡;要求更"新鲜"可缩短,但别低于 5 分钟(意义不大且增负担)。
- **主动刷新**:可在 TTL 到期前用后台任务预热,避免首个用户触发回源延迟。
- **文档未标注限流**:以上为稳妥实践,不假设具体阈值;若平台给出明确 QPS,按官方值收紧。
## FAQ
**Q1:免费接口也会被限流吗?**
A1:文档未公开限流规则,但任何接口都可能有频率约束。缓存是低成本保险,建议默认开启。
**Q2:缓存过期期间用户看到旧数据有问题吗?**
A2:热搜变化慢,30 分钟内的旧数据对绝大多数场景无影响;且可配置"过期后仍返回旧值、后台异步刷新"的 stale-while-revalidate 策略。
**Q3:按 tab 缓存还是按整接口缓存?**
A3:按 `tab`(含 `category`/`country`)分桶更细,命中率更高,推荐。
**Q4:缓存 key 里 country 为空怎么处理?**
A4:统一用空串占位(如 `hotword:game::`),保持 key 规则稳定即可。
**Q5:需要和分类缓存一起设计吗?**
A5:313-1 的分类树变化更慢,可设更长 TTL(如 6~12 小时),见[分类查询篇](https://www.showapi.com/guides/hotword-category-query-313)。
## 相关能力 / 下一步阅读
- [搭建实时热搜看板:网络搜索热词排行 + 定时拉取的完整设计](https://www.showapi.com/guides/hotword-dashboard-313)
- [地区与子分类筛选:country/category 参数正确使用姿势](https://www.showapi.com/guides/hotword-country-category-313)
- [网络搜索热词排行返回字段全解:name/num/level/trend 一文读懂](https://www.showapi.com/guides/hotword-response-fields-313)
- **本系列共 12 篇**:查看[网络搜索热词排行开发指南总目录](https://www.showapi.com/guides/hotword-guides-313)