【Python入门】用 requests 调 API 获取天气数据,一周学完 Python 基础
·
【Python入门】用 requests 调 API 获取天气数据,一周学完 Python 基础
学 Python 一周能做什么?这篇文章带你从零调天气 API,用类封装成 Weather_manage,最后回顾第一周 7 天的学习成果。
一、先看问题
想获取任意城市的实时天气数据,怎么做?
输入:城市名 "Beijing"
输出:气温 23.45°C,湿度 45%,风速 3.5m/s ...
答案:调天气 API,用 Python 解析返回的 JSON 数据。
二、requests 基础:5 分钟学会调 API
1. HTTP 请求方法
| 方法 | 用途 | 类比 |
|---|---|---|
| GET | 获取数据 | 打开网页看内容 |
| POST | 提交数据 | 填表单提交 |
| PUT | 修改数据 | 编辑已有内容 |
| DELETE | 删除数据 | 删除一条记录 |
2. 发送请求
import requests
url = 'https://api.example.com/data'
params = {'key': 'value'} # GET 请求参数
response = requests.get(url, params=params, timeout=5)
3. response 对象常用属性
| 属性 | 说明 | 示例 |
|---|---|---|
status_code |
状态码 | 200 成功,404 未找到,500 服务器错误 |
text |
文本内容 | '{"temp": 23}' |
json() |
解析为字典 | {'temp': 23} |
encoding |
编码格式 | 'utf-8' |
headers |
响应头 | {'Content-Type': 'application/json'} |
4. 异常处理
try:
response = requests.get(url, params=params, timeout=5)
if response.status_code == 200:
data = response.json()
print(data)
else:
print(f'请求失败,状态码:{response.status_code}')
except Exception as e:
print(f'请求出错:{e}')
💡 timeout=5 表示 5 秒没响应就超时,防止程序卡死。
三、实战:获取天气数据
我使用的是 OpenWeatherMap,需要先注册账号获取 API Key。
第 1 版:直接调 API,打印原始数据
import requests
params = {'q': 'Beijing', 'appid': '你的API Key'}
url = 'https://api.openweathermap.org/data/2.5/weather'
response = requests.get(url, params=params)
print(response.json())
输出一大堆 JSON,看不懂?没关系,下一步提取关键信息。
第 2 版:解析 JSON,提取关键信息
def get_weather(city='Beijing'):
params = {'q': city, 'appid': '你的API Key'}
url = 'https://api.openweathermap.org/data/2.5/weather'
mydata = {}
try:
response = requests.get(url, params=params)
if response.status_code == 200:
data = response.json()
mydata['城市'] = data.get('name', '未知')
mydata['天气'] = data['weather'][0]['description']
mydata['气温'] = data['main']['temp']
mydata['湿度'] = data['main']['humidity']
mydata['风速'] = data['wind']['speed']
except Exception as e:
print(f'请求出错:{e}')
return mydata
print(get_weather('Beijing'))
# → {'城市': 'Beijing', '天气': 'clear sky', '气温': 296.45, ...}
等等,气温 296.45?这是开尔文!不是摄氏度!
第 3 版:开尔文转摄氏度
def K2C(kelvin):
"""开尔文转摄氏度,保留2位小数"""
return f'{(kelvin - 273.15):.2f}'
print(K2C(296.45)) # → '23.30'
⚠️ 踩坑:OpenWeatherMap 默认返回开尔文温度,不是摄氏度!需要在请求参数加
units=metric才能直接获取摄氏度,或者自己写转换函数。
四、用类封装:Weather_manage
为什么要用类?
# 函数写法:每次都要传 url 和 appid
get_weather('Beijing', url='...', appid='...')
get_weather('Shanghai', url='...', appid='...')
# 类写法:url 和 appid 只需初始化一次
wm = Weather_manage(appid='你的API Key')
wm.get_weather('Beijing')
wm.get_weather('Shanghai')
wm.save_to_json('Beijing') # 还能直接保存文件
类 = 把重复的参数和逻辑打包,用起来更简洁。
Weather_manage 完整代码
import json
import requests
class Weather_manage(object):
def __init__(self, appid):
self.__url = 'https://api.openweathermap.org/data/2.5/weather'
self.__appid = appid
self.result = {} # ← 实例变量,每个对象独立
def _parse_weather(self, data):
"""解析天气数据(私有方法,避免重复代码)"""
self.result['城市'] = data.get('name', '未知')
self.result['天气'] = data['weather'][0]['description']
self.result['气温'] = self.K2C(float(data['main']['temp']))
self.result['体感温度'] = self.K2C(float(data['main']['feels_like']))
self.result['最低温'] = self.K2C(float(data['main']['temp_min']))
self.result['最高温'] = self.K2C(float(data['main']['temp_max']))
self.result['湿度'] = data['main']['humidity']
self.result['风速'] = data['wind']['speed']
self.result['风向'] = data['wind'].get('deg', 'N/A')
return self.result
def getWeatherByCity(self, city='Beijing'):
params = {'q': city, 'appid': self.__appid}
try:
response = requests.get(url=self.__url, params=params)
if response.status_code == 200:
return self._parse_weather(response.json())
except Exception as e:
print(f'请求出错:{e}')
return {}
def getWeatherByLatAndLon(self, lat=44.34, lon=10.99):
params = {'lat': lat, 'lon': lon, 'appid': self.__appid}
try:
response = requests.get(url=self.__url, params=params)
if response.status_code == 200:
return self._parse_weather(response.json())
except Exception as e:
print(f'请求出错:{e}')
return {}
def save_to_json(self, city='Beijing'):
"""获取天气并保存为 JSON 文件"""
self.getWeatherByCity(city)
filename = city + '.json'
with open(filename, 'w', encoding='utf-8') as f:
json.dump(self.result, f, ensure_ascii=False, indent=2)
def K2C(self, kelvin):
"""开尔文转摄氏度"""
return f'{(kelvin - 273.15):.2f}'
使用示例
wm = Weather_manage(appid='你的API Key')
# 按城市查询
beijing = wm.getWeatherByCity('Beijing')
print(beijing)
# → {'城市': 'Beijing', '天气': 'clear sky', '气温': '23.30', ...}
# 按经纬度查询
loc = wm.getWeatherByLatAndLon(lat=39.9, lon=116.4)
# 保存为 JSON 文件
wm.save_to_json('Beijing') # → Beijing.json
类变量 vs 实例变量的坑
# ❌ 错误:result 定义在类里(类变量),所有实例共享
class Weather_manage:
result = {} # 所有对象共享同一个 result!
w1 = Weather_manage()
w2 = Weather_manage()
w1.getWeatherByCity('Beijing')
w2.getWeatherByCity('Shanghai')
print(w1.result) # → 上海的数据!北京的被覆盖了!
# ✅ 正确:result 定义在 __init__ 里(实例变量),每个实例独立
class Weather_manage:
def __init__(self):
self.result = {} # 每个对象独立的 result
w1 = Weather_manage()
w2 = Weather_manage()
w1.getWeatherByCity('Beijing')
w2.getWeatherByCity('Shanghai')
print(w1.result) # → 北京的数据 ✅
五、踩坑记录
坑 1:API 返回的温度是开尔文
data['main']['temp'] # → 296.45(开尔文,不是摄氏度!)
解决:写 K2C() 转换函数,或在请求参数加 units=metric。
坑 2:类变量 result 被多个实例共享
result = {} 写在类里是类变量,所有实例共享同一个字典。必须放在 __init__ 里变成实例变量。
坑 3:JSON 保存中文乱码
# ❌ 中文变成 \uXXXX
json.dump(data, f)
# ✅ 加 ensure_ascii=False 保留中文
json.dump(data, f, ensure_ascii=False, indent=2)
六、第一周总结
| 天 | 学了什么 | 做了什么 |
|---|---|---|
| Day 1 | 变量、运算符、字符串 | 计算器 |
| Day 2 | 数据结构、推导式 | 词频统计 |
| Day 3 | 流程控制 | 猜数字游戏 |
| Day 4 | 函数、闭包、装饰器 | 闭包陷阱实验 |
| Day 5 | 文件读写、CSV/JSON | 学生成绩计算 |
| Day 6 | 类、继承、多态 | FileManager 类 |
| Day 7 | requests 调 API | Weather_manage 类 |
7 天从零基础到能用类封装 API 调用,这就是每天 8 小时的力量。
七、下一步:SQL + PostgreSQL
📌 Python 基础告一段落,接下来进入数据工程的核心——SQL。下一篇:SQL 入门,从 SELECT 到 JOIN。
更多推荐

所有评论(0)