历史上的今天:教育/课堂场景如何集成历史事件 API?
# 历史上的今天:教育/课堂场景如何集成历史事件 API?
> 接口:历史上的今天(apiCode=119,接入点 119-42)· 免费 · 适用人群:教师、教育内容编辑、K12 产品 · 阅读时间:约 7 分钟
## 核心要点
- 「每日一史」是最自然的用法:不传 `date` 默认查今天,每天自动换新。
- 用 `needContent=1` 拿到 `content` 做延伸阅读,数据落本地表便于检索/批注。
- 课堂晨读组件 = 定时拉取 + 卡片轮播 + 点击展开详情,前端几十行即可实现。
## Why:让历史"每天发生一次"
历史课最怕枯燥。"历史上的今天"能把课本外的真实大事,按学生**当下日期**推到眼前——今天发生了什么?哪位科学家、哪场变革、哪次探索?把它做成每日晨读或课后一分钟,比背年代更有代入感。接口免费、结构干净,教育场景零成本接入。
## What:前置与数据表设计
| 项目 | 说明 |
|------|------|
| 触发方式 | 每天固定时刻(如 07:30)由服务端/定时任务拉取"今天"事件 |
| 请求参数 | 不传 `date`(默认今天)+ `needContent=1`(要详情) |
| 存储 | 落本地表 `history_daily(date, year, month, day, title, content, img)`,按 `date` 去重 |
数据表建议字段:
```
date VARCHAR(4) -- MMDD,如 0220,主键/唯一
year VARCHAR(4)
month INT
day INT
title TEXT
content TEXT
img TEXT -- 空字符串表示无图
fetched_at DATETIME
```
## How:从拉取到展示
### 步骤 1:服务端定时拉取并入库(Python)
```python
import requests, sqlite3, datetime
def fetch_today():
url = "https://route.showapi.com/119-42"
params = {"appKey": "YOUR_APPKEY"}
data = {"needContent": "1"} # 不传 date = 今天
resp = requests.post(url, params=params, data=data, timeout=10)
body = resp.json()["showapi_res_body"]
today = datetime.date.today().strftime("%m%d")
rows = [(today, it["year"], it["month"], it["day"], it["title"],
it.get("content", ""), it.get("img", "")) for it in body["list"]]
return today, rows
# 入库(按 date 去重,每日仅存一次)
con = sqlite3.connect("history.db")
con.execute("""CREATE TABLE IF NOT EXISTS history_daily(
date TEXT, year TEXT, month INT, day INT, title TEXT, content TEXT, img TEXT,
PRIMARY KEY(date, title))""")
today, rows = fetch_today()
con.executemany("INSERT OR IGNORE INTO history_daily VALUES(?,?,?,?,?,?,?)", rows)
con.commit()
print(f"已存入 {today} 的 {len(rows)} 条事件")
```
### 步骤 2:课堂卡片前端(HTML/JS 片段)
```html
<div id="history-card">
<h3 id="h-title"></h3>
<img id="h-img" alt="" style="max-width:100%" onerror="this.style.display='none'">
<p id="h-content"></p>
</div>
<script>
async function loadToday() {
const r = await fetch("/api/history-today"); // 你的后端返回今日缓存
const list = await r.json();
let i = 0;
const show = (it) => {
document.getElementById("h-title").textContent = it.title;
const img = document.getElementById("h-img");
if (it.img) { img.src = it.img; img.style.display = ""; }
else { img.style.display = "none"; }
document.getElementById("h-content").textContent = it.content || "";
};
show(list[i]);
// 每 8 秒轮播一条
setInterval(() => { i = (i + 1) % list.length; show(list[i]); }, 8000);
}
loadToday();
</script>
```
### 步骤 3:延伸阅读批注
把 `content` 落到本地表后,老师可在 `content` 旁加"延伸问题""相关课文"字段,形成校本素材库。
## 返回示例与解析
同一天可返回数十条事件(实测 2 月 20 日返回 30+ 条),涵盖国内外、古今。课堂可按主题筛选(科技、军事、文化),用 `title` 关键词过滤后再展示。
## 进阶 / 边界
- **量级**:单日事件可能几十条,前端务必做轮播/分页,避免一屏刷屏。
- **无图兜底**:大量事件 `img` 为 `""`,用 `onerror` 隐藏或显示占位图。
- **节假日/寒暑假**:学校场景可只在教学日拉取与展示,避免假期空转。
## FAQ
**Q1:能不能只拉"科技类"事件?**
接口按日期返回全部事件,不按主题筛选。可用 `title` 关键词在本地做分类/过滤。
**Q2:每天拉一次还是每次打开都拉?**
建议服务端每日定时拉一次入库(见缓存篇),前端读本地缓存,免费额度更省、也更稳。
**Q3:content 很长怎么展示?**
卡片显示 `title`,点击"展开详情"再显示 `content`;或截断 + "阅读全文"。
**Q4:寒暑假要不要停?**
按你的教学日历控制拉取/展示即可,接口本身不限时间。
## 相关能力 / 下一步阅读
- [历史上的今天:免费接口下如何做本地缓存与更新频率设计?](https://www.showapi.com/guides/history-today-cache-119) — 每日入库的缓存逻辑。
- [历史上的今天:needContent 参数与图文详情的正确打开方式](https://www.showapi.com/guides/history-today-needcontent-119) — 详情开关。
- [历史上的今天:网站/App 每日历史卡片组件集成指南](https://www.showapi.com/guides/history-today-widget-119) — 可复用的组件形态。
- **本系列共 10 篇**:查看[历史上的今天指南总目录](https://www.showapi.com/guides/history-today-guides-119)