Python使用requests解析PokeAPI JSON时如何正确提取字典键值对
问题原因
response.json()已经将接口返回的JSON字符串转换为Python字典,无需再调用json.loads()处理,所以会出现参数类型错误。- 你注释里的取值代码漏了键的引号,正确写法是
fetch['damage_relations']['double_damage_from']。
实现方案
不需要硬编码嵌套循环,我们可以通过「先算每个攻击属性的总伤害倍率,再分类存入deals字典」的逻辑实现需求,自动处理双属性的倍率叠加:
- 先定义API字段和倍率的映射关系
- 查询目标宝可梦的属性列表
- 遍历所有属性拉取克制关系,累乘计算每个攻击属性的总倍率
- 按总倍率将属性分类到deals的对应列表
完整代码示例
import requests from collections import defaultdict # 定义API字段和倍率的映射关系 DAMAGE_FIELD_MAP = { "double_damage_from": 2, "half_damage_from": 0.5, "no_damage_from": 0 } @bot.command(name="weak", aliases=['w']) async def weakness(ctx, *, msg): deals = {'4x': [], '2x': [], '1x': [], '0.5x': [], '0.25x': [], '0x': []} # 初始化倍率计算器,所有属性默认倍率为1 dmg_calc = defaultdict(lambda: 1) try: # 1. 先查询宝可梦基础信息,获取属性列表 pokemon_name = msg.strip().lower() pokemon_resp = requests.get(f"https://pokeapi.co/api/v2/pokemon/{pokemon_name}") pokemon_resp.raise_for_status() pokemon_data = pokemon_resp.json() pokemon_types = [t['type']['name'] for t in pokemon_data['types']] # 2. 遍历每个属性拉取克制关系,累乘倍率 for p_type in pokemon_types: type_resp = requests.get(f"https://pokeapi.co/api/v2/type/{p_type}") type_resp.raise_for_status() type_data = type_resp.json() damage_relations = type_data['damage_relations'] for field, multiplier in DAMAGE_FIELD_MAP.items(): for entry in damage_relations[field]: atk_type = entry['name'] dmg_calc[atk_type] *= multiplier # 3. 按倍率分类存入deals字典 for atk_type, total_multi in dmg_calc.items(): deals[f"{total_multi}x"].append(atk_type) # 4. 拼接返回结果,可根据自己需要调整输出格式 res = f"【{pokemon_name.title()} 克制关系】\n" for multi, types in deals.items(): if types: res += f"{multi} 伤害: {'、'.join(types)}\n" await ctx.send(res) except requests.exceptions.HTTPError: await ctx.send("未找到对应宝可梦,请检查输入名称是否正确")
内容的提问来源于stack exchange,提问作者YeYeeeeee
相关产品推荐
相关产品推荐

