最近刷宝可梦相关视频时,经常看到“小锻匠”“下石鸟”这些新世代的宝可梦被反复讨论。作为一个习惯了数据处理的技术人,我的第一反应不是去猜剧情,而是想着一个问题:这些宝可梦的种族值、进化链、属性分布,能不能用 Python 快速抓到本地,做成一张结构清晰的表格,再画几条变化曲线?
答案是肯定的。宝可梦领域有一个公开的 REST API 叫做 PokeAPI,不需要注册,不需要 API Key,用requests就能拿到结构化的 JSON 数据。这篇文章就围绕 PokeAPI 做一次完整的数据链路实践:从获取单只宝可梦数据开始,到解析嵌套的进化链,再到用 pandas 组装表格、用 matplotlib 输出可视化,最终跑通一条“拉取、清洗、分析、展示”的完整流程。
读完本文,你会掌握:PokeAPI 中 Pokemon、PokemonSpecies、EvolutionChain 三个核心资源之间的关系;如何用 requests 获取宝可梦基础数据,并提取种族值、属性等关键字段;如何解析嵌套结构的进化链,把小锻匠(Tinkatink)这种多段进化关系变成一行行规整数据;如何用 pandas 把多个进化阶段合并成一张表,并用图表展示进化带来的种族值变化。
如果你正在学 Python 数据分析,或者想拿一个有趣的主题练手爬虫和 JSON 解析,这篇文章可以直接照着做。
1. 这篇文章真正要解决的问题
先说说痛点。喜欢宝可梦的玩家都知道,图鉴中每只宝可梦都包含大量数据:编号、属性、种族值、身高、体重、特性、进化条件。这些数据散布在游戏、攻略站和百科中。如果需要把所有宝可梦的进化关系整理成一张表,手工复制粘贴几乎不可行,而且容易出错。
更麻烦的是进化链的结构。宝可梦的进化不是简单的线性关系,有的宝可梦只有一个最终形态,有的有分支进化,有的需要特定道具或亲密度才能进化。这些关系在 JSON 中表现为嵌套对象,写代码时容易卡在递归解析上。
PokeAPI 解决了“数据从哪里来”这个问题,但它不负责“数据怎么用”。它提供的是原始 JSON,需要开发者自己请求、解析、清洗和结构化。
所以这篇文章真正要解决的问题有三个:
第一,如何用规范的方式从 PokeAPI 拉取数据,而不是写死 URL 后手工拷贝 JSON。第二,如何把嵌套的进化链对象转换为扁平的表格结构,方便后续分析。第三,如何把不同进化阶段的数据放在一起,用可视化直观地展示进化带来的属性变化。
对你来说,跑通这条链路后,再遇到其他嵌套 JSON 数据源,比如订单树、组织架构、评论回复链,都可以套用同样的思路。这也是这类练习的真正价值。
2. PokeAPI 核心概念与数据模型
PokeAPI 是社区维护的免费宝可梦数据接口,返回 JSON 格式,支持按名字或数字 ID 查询。它数据量很大,涵盖了历代宝可梦图鉴、招式、特性、地点等内容。URL 基础地址是:
https://pokeapi.co/api/v2本文只使用其中三个资源:
| 资源 | 接口路径 | 作用 |
|---|---|---|
| Pokemon | /pokemon/{name} | 返回宝可梦基础数据,包含种族值、属性、身高、体重、图片等 |
| PokemonSpecies | /pokemon-species/{name} | 返回宝可梦物种信息,包含进化来源、图鉴编号、捕获率等 |
| EvolutionChain | /evolution-chain/{id} | 返回一段进化链的树形结构,是进化关系最直接的来源 |
这三个资源之间的关系可以这样理解:Pokemon表示“一只具体的宝可梦实例”,PokemonSpecies表示“这个宝可梦作为一个物种的元信息”,EvolutionChain表示“从初始形态到最终形态的完整进化关系”。
通过Pokemon返回中的species.url可以拿到PokemonSpecies数据;PokemonSpecies返回中的evolution_chain.url可以跳到EvolutionChain。整条链路是:
/pokemon/{name} -> /pokemon-species/{name} -> /evolution-chain/{id}很多初学者第一次看接口文档时容易被绕晕,这里有一个关键点:进化链是“嵌套对象”,不是“扁平列表”。一个典型的进化链 JSON 长这样(结构示意,字段以实际返回为准):
{ "id": 123, "chain": { "species": {"name": "tinkatink"}, "evolution_details": [], "evolves_to": [ { "species": {"name": "tinkatuff"}, "evolution_details": [], "evolves_to": [ { "species": {"name": "tinkaton"}, "evolution_details": [], "evolves_to": [] } ] } ] } }可以看到,chain是根,根节点代表进化链的初始形态;evolves_to是一个数组,表示当前形态可以进化成哪些形态;数组里的每个元素又是一个相同的结构,因此可以继续嵌套。这就是为什么解析进化链要用递归:因为它的深度不确定,但结构自相似。
本节的小结论:PokeAPI 的数据模型并不复杂,关键是理解从 Pokemon 到 Species 再到 EvolutionChain 的跳转关系,以及进化链 JSON 的自相似嵌套结构。搞懂这两点,下面的代码就顺理成章了。
3. 环境准备与依赖安装
本文所有代码使用 Python 编写。建议使用 Python 3.8 或更高版本,Windows、macOS、Linux 均可。依赖只有三个:
- requests:发起 HTTP 请求,获取 JSON;
- pandas:把数据整理成表格;
- matplotlib:绘制进化趋势图。
在项目目录下创建一个虚拟环境(可选但推荐):
mkdir pokemon-analysis cd pokemon-analysis python -m venv .venv source .venv/bin/activate # Windows 用户改为 .venv\Scripts\activate安装依赖:
pip install requests pandas matplotlib如果下载速度慢,可以临时使用国内镜像源:
pip install requests pandas matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple安装完成后验证一下:
python -c "import requests, pandas, matplotlib; print('deps ok')"看到deps ok就说明环境没问题。
注意:这个项目需要能正常访问 PokeAPI 的网络环境。可以先执行下面的命令测试连通性:
curl https://pokeapi.co/api/v2/pokemon/pikachu如果能返回 JSON 数据,说明网络正常。
环境准备到这里就算完成。这个项目对第三方包的版本要求并不敏感,最新的稳定版本都可以正常工作,不必刻意锁定版本号。
4. 获取宝可梦基础数据
第一步,先从最简单的开始:获取宝可梦基础数据。这里先用皮卡丘(Pikachu)做标准示例,因为它的数据最稳定也最容易被验证。代码要做的核心事情是:拼接接口地址、发起请求、把返回 JSON 中我们关心的字段提取出来。
# 文件路径:pokemon_api.py import requests BASE_URL = "https://pokeapi.co/api/v2" def get_pokemon(name_or_id): """根据宝可梦名称或编号获取基础数据""" url = f"{BASE_URL}/pokemon/{str(name_or_id).lower()}" resp = requests.get(url, timeout=10) resp.raise_for_status() data = resp.json() stats = {item["stat"]["name"]: item["base_stat"] for item in data["stats"]} types = [item["type"]["name"] for item in data["types"]] return { "id": data["id"], "name": data["name"], "height": data["height"], "weight": data["weight"], "types": types, "stats": stats, } if __name__ == "__main__": info = get_pokemon("pikachu") print(info)代码里做了几件事:
- 拼接
/pokemon/{name}接口地址,name统一转小写; - 调用
requests.get并设置超时时间; - 拿到 JSON 后,把
stats数组转换成字典,key 是速度、攻击、防御等属性名; - 把
types数组提取为字符串列表; - 返回简化后的字典。
运行:
python pokemon_api.py预期输出大致