exercises-dataset:1324 条健身动作数据集的安装与接入指南

介绍 hasaneyldrm/exercises-dataset 的数据内容、安装方式、本地浏览、JSON 读取、数据库导入和 API 接入流程,并提醒媒体资源、字段差异与授权注意事项。

hasaneyldrm/exercises-dataset 是一个面向健身应用开发者的开源数据集。项目把健身动作整理成结构化 JSON,并提供两个纯前端页面:index.html 用来本地浏览动作,setup.html 用来生成数据库导入 SQL、API 调用示例和后端开发提示词。

项目 README 标注的数据规模为 1,324 条动作记录,包含动作名称、分类、目标肌肉、器械、辅助肌群、分步骤说明和多语言说明。它适合用于健身 App 原型、训练计划工具、动作搜索页、推荐系统实验,或作为生成健身 API 后端时的基础数据。

接入前要先注意一件事:仓库不随项目分发图片和 GIF。imagegif_url 这类字段即使存在,也不要直接当作可用媒体文件处理;实际展示时应准备空状态,或接入自己有权使用的图片、视频资源。

适合什么场景

这个项目不是完整健身应用,而是可以接入应用的数据底座。它主要由三部分组成:

  • data/exercises.json:核心数据文件,应用读取的主要对象。
  • index.html:本地动作浏览器,可搜索和筛选动作。
  • setup.html:开发者集成向导,可生成数据库 SQL、API 示例和 LLM 提示词。

如果只是快速查看数据,打开 index.html 就够了。如果要放进自己的产品,建议从 data/exercises.json 开始,先确认字段结构,再决定是直接读取 JSON、导入数据库,还是在后端封装一层 REST API。

下载与安装

最简单的方式是克隆仓库:

1
2
git clone https://github.com/hasaneyldrm/exercises-dataset.git
cd exercises-dataset

仓库主要是静态文件,不需要 npm install,也没有必须启动的后端服务。目录大致如下:

1
2
3
4
5
6
exercises-dataset/
├── data/
│   └── exercises.json
├── index.html
├── setup.html
└── README.md

如果只需要数据文件,也可以直接下载 raw JSON:

1
curl -L -o exercises.json https://raw.githubusercontent.com/hasaneyldrm/exercises-dataset/main/data/exercises.json

Windows PowerShell 可以这样下载:

1
2
3
Invoke-WebRequest `
  -Uri "https://raw.githubusercontent.com/hasaneyldrm/exercises-dataset/main/data/exercises.json" `
  -OutFile "exercises.json"

下载后建议先确认 JSON 可以正常解析:

1
python -m json.tool data/exercises.json > /tmp/exercises.pretty.json

Windows 下可以用:

1
python -m json.tool .\data\exercises.json > .\exercises.pretty.json

如果这一步报错,通常说明文件没有下载完整,先重新拉取仓库或重新下载 JSON。

本地浏览数据

index.html 是纯前端浏览器,可以直接打开:

1
2
3
4
5
# macOS
open index.html

# Windows PowerShell
Start-Process .\index.html

它适合快速检查动作数据:搜索动作名称,按分类、器械或目标肌肉筛选,点开卡片查看说明。因为媒体资源没有随仓库分发,所以图片或 GIF 为空并不代表数据加载失败。

如果浏览器限制本地文件读取,可以在仓库目录启动一个临时静态服务:

1
python -m http.server 8000

然后访问:

1
http://localhost:8000/index.html

Node.js 用户也可以使用:

1
npx serve .

使用 setup.html 生成数据库和 API 示例

setup.html 面向准备集成数据的开发者,打开方式和 index.html 一样。推荐通过本地静态服务访问:

1
python -m http.server 8000

然后打开:

1
http://localhost:8000/setup.html

页面主要做三件事。

第一,生成数据库结构和导入 SQL。它支持 SQL Server、PostgreSQL、MySQL、SQLite 等数据库类型,可以复制 CREATE TABLE,也可以生成包含全部动作数据的 INSERT SQL 文件。这个过程在浏览器本地完成,不需要上传数据。

第二,生成 API 调用示例。你可以填入自己的 API base URL,页面会生成 cURL、JavaScript、Python、C#、Java、PHP、Go 等语言的请求示例。常见接口形态包括:

1
2
3
GET /exercises/:id
GET /exercises?page=1&limit=20
GET /exercises?category=Strength&body_part=Chest

这些接口不是仓库已经提供的线上服务,而是建议你在自己的后端中实现的 API 形态。

第三,生成 LLM 提示词。页面可以按框架和数据库组合输出提示词,例如 Express.js + PostgreSQL、FastAPI + SQLite、Spring Boot + MySQL、ASP.NET Core + SQL Server、Laravel 或 Gin。你可以把提示词交给模型,用它生成后端骨架代码。

直接读取 JSON

小型应用或原型项目可以直接读取 data/exercises.json

Python 示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import json

with open("data/exercises.json", "r", encoding="utf-8") as f:
    exercises = json.load(f)

print("动作总数:", len(exercises))

bodyweight = [item for item in exercises if item.get("equipment") == "body weight"]
print("自重动作:", len(bodyweight))

first = exercises[0]
print(first["id"], first["name"])
print(first.get("instructions", {}).get("en"))

Node.js 示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
const exercises = require("./data/exercises.json");

console.log("Total:", exercises.length);

const bodyweight = exercises.filter((item) => item.equipment === "body weight");
const byCategory = exercises.reduce((acc, item) => {
  const key = item.category || "unknown";
  acc[key] = acc[key] || [];
  acc[key].push(item);
  return acc;
}, {});

console.log("Bodyweight:", bodyweight.length);
console.log(Object.keys(byCategory));

前端项目可以把 JSON 放到 public/data/exercises.json,再用 fetch 加载:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
async function loadExercises() {
  const res = await fetch("/data/exercises.json");
  if (!res.ok) {
    throw new Error(`Failed to load exercises: ${res.status}`);
  }
  return await res.json();
}

loadExercises().then((exercises) => {
  console.log(exercises.length);
});

如果使用 TypeScript,字段最好写成保守的可选类型,避免仓库后续调整字段时让应用直接崩掉:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
type Exercise = {
  id: string;
  name: string;
  category?: string;
  body_part?: string;
  equipment?: string;
  target?: string;
  muscle_group?: string;
  secondary_muscles?: string[];
  instructions?: Record<string, string>;
  instruction_steps?: Record<string, string[]>;
  media_id?: string | null;
  image?: string | null;
  gif_url?: string | null;
  created_at?: string;
};

导入数据库

正式产品更适合把数据导入数据库。这样分页、筛选、搜索、后台编辑和 API 权限控制都会更容易做。

一个常见表结构可以这样设计:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
CREATE TABLE exercises (
  id VARCHAR(32) PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  category VARCHAR(100),
  body_part VARCHAR(100),
  equipment VARCHAR(100),
  target VARCHAR(100),
  muscle_group VARCHAR(100),
  secondary_muscles JSON,
  instructions JSON,
  instruction_steps JSON,
  image VARCHAR(255),
  gif_url VARCHAR(255),
  media_id VARCHAR(100),
  created_at VARCHAR(64)
);

PostgreSQL 可以把 JSON 字段改为 jsonb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
CREATE TABLE exercises (
  id text PRIMARY KEY,
  name text NOT NULL,
  category text,
  body_part text,
  equipment text,
  target text,
  muscle_group text,
  secondary_muscles jsonb,
  instructions jsonb,
  instruction_steps jsonb,
  image text,
  gif_url text,
  media_id text,
  created_at text
);

导入流程建议按这个顺序做:

  1. setup.html 生成目标数据库的建表 SQL 和 INSERT SQL。
  2. 先导入本地库或测试库,不要直接写入生产库。
  3. 检查导入行数是否等于 JSON 数组长度。
  4. categorybody_partequipmenttarget 增加普通索引。
  5. 如果要做关键词搜索,再考虑全文索引或外部搜索服务。

PostgreSQL 索引示例:

1
2
3
4
CREATE INDEX idx_exercises_category ON exercises(category);
CREATE INDEX idx_exercises_body_part ON exercises(body_part);
CREATE INDEX idx_exercises_equipment ON exercises(equipment);
CREATE INDEX idx_exercises_target ON exercises(target);

API 可以先实现四类接口:

1
2
3
4
GET /exercises
GET /exercises/:id
GET /exercises?category=chest
GET /exercises?equipment=body%20weight

分页参数建议统一为:

1
page=1&limit=20

响应结构保持稳定:

1
2
3
4
5
6
{
  "items": [],
  "page": 1,
  "limit": 20,
  "total": 1324
}

这样前端列表、筛选器和无限滚动都比较好接。

媒体资源怎么处理

README 对媒体资源的说明很关键:不要默认仓库里包含可直接使用的动作图片和 GIF。项目保留的是结构化动作数据和媒体引用,媒体文件本身没有随仓库重新分发。

实际项目可以采用三种方式:

  • 只使用文字数据,不展示图片和 GIF。
  • 准备自有授权的动作图片或视频,再用 id、动作名称或 media_id 建立映射。
  • 如果你有权使用原始 ExerciseDB 媒体资源,再按对应条款接入 CDN 或资源地址。

不要把 imagegif_url 字段直接当作仓库内一定存在的文件。接入前可以检查:

1
2
ls images
ls videos

如果目录不存在,应用就需要给媒体区域做空状态,或者隐藏图片和动画入口。

常见接入问题

第一,字段可能变化。README、页面示例和 raw JSON 的字段不一定永远一致,代码里不要把所有字段都写成必填。媒体、多语言说明和辅助字段尤其适合用可选读取。

第二,分类值通常是英文。比如 chestbackupper legsbody weight。如果前端展示中文,建议在应用层做一层映射:

1
2
3
4
5
6
7
8
const categoryLabel = {
  chest: "胸部",
  back: "背部",
  waist: "腰腹",
  "upper legs": "大腿",
  "upper arms": "上臂",
  shoulders: "肩部",
};

第三,动作说明不是医疗建议。它适合做产品原型、教学内容和动作检索数据,但正式健身产品仍应加入安全提示、禁忌说明和专业审核流程。

第四,商业使用前要重新确认授权。README 已经说明基础数据来源、媒体不分发原因和权利声明。上线前应重新检查 ExerciseDB、可能的 re-host 来源以及本仓库的许可证条款。

推荐接入路线

如果只是做演示,可以直接 git clone,打开 index.html,再从 data/exercises.json 读取数据。

如果要做完整健身应用,建议按这个顺序推进:

  1. 克隆仓库,并固定一个 commit,避免后续字段变化影响项目。
  2. 检查 data/exercises.json 的实际字段和语言覆盖。
  3. setup.html 生成数据库 SQL,导入测试库。
  4. 实现 /exercises/exercises/:id、筛选和分页 API。
  5. 前端先展示文字数据,媒体区域先做空状态。
  6. 根据授权情况补充自有图片、GIF 或视频。

这条路线简单、可控,也能避开媒体授权问题。exercises-dataset 最有价值的地方,是把健身动作知识整理成了可读取、可检索、可导入的数据结构;图片展示、训练计划逻辑和个性化推荐,则更适合放到自己的应用层继续完善。

记录并分享
使用 Hugo 构建
主题 StackJimmy 设计