discord.py中如何从API获取JSON数据并以embed形式发送天气查询结果
修正方案
你的代码主要存在三类错误:
- Python字典取值方式错误:调用
response.json()后得到的是嵌套字典,只能通过dict[key]的方式取值,不能使用.xxx()的方法调用写法 - 字段归属与拼写错误:比如
wind_kph属于current字段而非location,风向字段应为wind_dir而非你写的vwind_dir - Embed组装时存在语法错误,部分字段的value、最终发送的embed参数未补全
修正后的完整可运行代码如下:
import discord from discord.ext import commands import requests # 高并发场景建议替换为异步的aiohttp库,避免阻塞机器人事件循环 # 替换为你自己的API接口地址和请求头 url = "你的天气API地址" headers = {"你的API鉴权头字段": "对应值"} @commands.command() async def weather(self, ctx, *, location_name): # 增加异常捕获,避免请求失败、地点不存在导致机器人直接报错 try: querystring = {"q": location_name} response = requests.get(url, headers=headers, params=querystring) response.raise_for_status() weather_data = response.json() # 按JSON层级正确提取字段 location = weather_data["location"]["name"] region = weather_data["location"]["region"] country = weather_data["location"]["country"] temperature = weather_data["current"]["temp_c"] condition = weather_data["current"]["condition"]["text"] wind_speed = weather_data["current"]["wind_kph"] wind_degree = weather_data["current"]["wind_degree"] wind_dir = weather_data["current"]["wind_dir"] humidity = weather_data["current"]["humidity"] feelslike = weather_data["current"]["feelslike_c"] condition_icon = weather_data["current"]["condition"]["icon"] # 组装Embed weather_embed = discord.Embed( title="天气信息", description=f"{location} 的实时天气情况", color=discord.Colour.random() ) # 大部分天气API返回的图标地址不带https前缀,此处做适配 icon_url = f"https:{condition_icon}" if not condition_icon.startswith("http") else condition_icon weather_embed.set_thumbnail(url=icon_url) weather_embed.add_field(name="地点", value=location, inline=True) weather_embed.add_field(name="行政区", value=region, inline=True) weather_embed.add_field(name="国家", value=country, inline=True) weather_embed.add_field(name="温度", value=f"{temperature} °C", inline=True) weather_embed.add_field(name="天气状况", value=condition, inline=True) weather_embed.add_field(name="体感温度", value=f"{feelslike} °C", inline=True) weather_embed.add_field(name="风速", value=f"{wind_speed} 公里/小时", inline=True) weather_embed.add_field(name="风向角度", value=f"{wind_degree}°", inline=True) weather_embed.add_field(name="风向", value=wind_dir, inline=True) weather_embed.add_field(name="湿度", value=f"{humidity}%", inline=True) await ctx.send(embed=weather_embed) except Exception as e: await ctx.send(f"查询失败,请检查输入的地名是否正确,错误信息:{str(e)}")
补充说明
- 参数写法
*, location_name可以支持带空格的地名查询,比如输入!weather New York也能正常识别 - 如果你的API返回的图标已经是完整的http/https地址,可以删掉图标地址的前缀适配逻辑
内容的提问来源于stack exchange,提问作者Abhishek kushwaha
相关产品推荐
相关产品推荐

