实战指南:调用免费天气预报API并解析JSON数据
2026/4/22 21:48:49 网站建设 项目流程

1. 天气预报API入门指南

天气预报API是开发者获取天气数据的便捷通道,就像点外卖时查看餐厅菜单一样简单。我刚开始接触这类API时,发现它们比想象中友好得多。以国内常用的免费天气接口为例,只需要一个城市代码就能获取该地完整的天气数据,返回的JSON格式数据就像拆快递一样容易解析。

这个接口最棒的地方在于完全免费,不需要复杂的注册流程,也没有烦人的验证码。实测下来,响应速度相当稳定,我在个人项目和小型商业应用中都用过,基本能满足日常需求。接口返回的数据包含温度、湿度、风力等基础信息,还有未来几天的预报,对于大多数天气类应用来说已经足够。

提示:虽然接口免费,但建议控制调用频率,避免对服务器造成过大压力

2. 获取城市代码的三种方法

2.1 官方文档查询

城市代码是调用天气API的关键,就像快递单号之于包裹查询。接口文档中通常会提供完整的城市代码表,但有时候找起来不太方便。我习惯把常用城市的代码保存在本地JSON文件中,这样开发时就能快速调用。比如北京是101010100,上海是101020100,这些常用代码用多了自然就记住了。

2.2 通过接口动态获取

更聪明的做法是写个简单的脚本自动获取所有城市代码。我常用的方法是先用接口获取省份列表,再根据省份获取下属城市。这样即使城市代码有更新,程序也能自动适应。下面是个Python示例:

import requests def get_city_codes(): # 这里替换为实际的省份列表接口 provinces = requests.get('API地址').json() city_codes = {} for province in provinces: cities = requests.get(f'城市列表API/{province}').json() city_codes.update({city['name']: city['code'] for city in cities}) return city_codes

2.3 第三方城市代码库

GitHub上有不少维护良好的城市代码库,比如china-region-codes项目。这些库通常更新及时,还包含行政区划变更历史。我在一个需要显示天气历史数据的项目中就用了这类库,省去了自己维护的麻烦。

3. 发起HTTP请求的实战技巧

3.1 基础请求示例

用Python发起请求简单得令人发指,三行代码就能搞定:

import requests response = requests.get('http://t.weather.itboy.net/api/weather/city/101010100') weather_data = response.json()

但实际项目中我建议加上异常处理和超时设置,网络请求总有各种意外情况。这是我优化后的版本:

try: response = requests.get( 'http://t.weather.itboy.net/api/weather/city/101010100', timeout=5 ) response.raise_for_status() weather_data = response.json() except requests.exceptions.RequestException as e: print(f"请求失败: {e}") weather_data = None

3.2 多城市批量请求

当需要获取多个城市天气时,同步请求效率太低。我推荐使用aiohttp库进行异步请求,速度能提升数倍。这是我项目中的实际代码片段:

import aiohttp import asyncio async def fetch_weather(session, city_code): url = f'http://t.weather.itboy.net/api/weather/city/{city_code}' async with session.get(url) as response: return await response.json() async def get_multiple_weather(city_codes): async with aiohttp.ClientSession() as session: tasks = [fetch_weather(session, code) for code in city_codes] return await asyncio.gather(*tasks)

3.3 请求头优化

有些API对请求头有要求,比如需要指定User-Agent。经过多次测试,我发现加上这些头信息能提高成功率:

headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)', 'Accept': 'application/json' } response = requests.get(url, headers=headers)

4. JSON数据解析全攻略

4.1 数据结构分析

典型的天气API返回数据像这样:

{ "data": { "forecast": [ { "date": "2023-05-01", "high": "28℃", "low": "18℃", "type": "晴" } ], "wendu": "22", "shidu": "45%", "pm25": 35 } }

我习惯先用JSON可视化工具查看整体结构,再决定如何解析。在线工具如JSON Viewer能帮我们快速理清数据层级。

4.2 安全解析技巧

直接访问嵌套字典容易引发KeyError,我推荐使用get()方法带默认值:

temperature = weather_data.get('data', {}).get('wendu', 'N/A')

更复杂的场景可以用try-except包裹,或者使用第三方库如python-box让字典访问更安全:

from box import Box weather = Box(weather_data) print(weather.data.forecast[0].high) # 像访问属性一样安全

4.3 数据清洗与转换

原始数据常需要清洗,比如温度字段"28℃"要去掉单位符号。我常用的处理函数:

def clean_weather_data(raw_data): cleaned = raw_data.copy() # 处理温度字段 for forecast in cleaned['data']['forecast']: forecast['high'] = int(forecast['high'].replace('℃', '')) forecast['low'] = int(forecast['low'].replace('℃', '')) # 转换湿度为浮点数 cleaned['data']['shidu'] = float(cleaned['data']['shidu'].replace('%', '')) / 100 return cleaned

5. 错误处理与性能优化

5.1 常见错误码处理

API可能返回各种错误,这是我整理的常见错误处理方案:

错误码含义处理建议
404城市代码错误检查城市代码有效性
429请求太频繁增加延迟或减少调用
500服务器错误等待后重试

实现示例:

if response.status_code == 404: print("城市代码不存在,请检查") elif response.status_code == 429: print("请求太频繁,稍后再试") time.sleep(60) # 等待1分钟

5.2 请求缓存策略

频繁请求相同数据既低效又可能触发限流。我推荐使用内存缓存,比如Python的functools.lru_cache:

from functools import lru_cache import time @lru_cache(maxsize=100) def get_weather_cached(city_code): # 实际请求代码 return weather_data

对于更长期的缓存,可以考虑Redis等专业方案。我在一个天气展示项目中用Redis缓存数据,设置15分钟过期,服务器负载降低了70%。

5.3 日志记录与分析

完善的日志能帮我们快速定位问题。这是我的日志配置示例:

import logging logging.basicConfig( filename='weather_api.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) try: # API调用代码 logging.info(f"成功获取{city_code}天气数据") except Exception as e: logging.error(f"获取{city_code}天气失败: {str(e)}")

6. 实际应用案例

6.1 命令行天气查询工具

用不到50行代码就能实现实用的命令行天气查询工具:

import argparse import requests def main(): parser = argparse.ArgumentParser(description='命令行天气查询') parser.add_argument('city', help='城市名称') args = parser.parse_args() # 这里应该有城市名到代码的转换逻辑 city_code = get_city_code(args.city) try: data = get_weather(city_code) print(f"{args.city}天气:") print(f"温度:{data['wendu']}℃") print(f"湿度:{data['shidu']}") print(f"天气:{data['forecast'][0]['type']}") except Exception as e: print(f"查询失败:{e}") if __name__ == '__main__': main()

6.2 天气数据可视化

用Matplotlib可以轻松实现天气趋势图:

import matplotlib.pyplot as plt dates = [f['date'] for f in forecast] highs = [int(f['high'].replace('℃', '')) for f in forecast] lows = [int(f['low'].replace('℃', '')) for f in forecast] plt.plot(dates, highs, 'r-', label='最高温') plt.plot(dates, lows, 'b-', label='最低温') plt.fill_between(dates, highs, lows, color='gray', alpha=0.1) plt.legend() plt.title('7天温度趋势') plt.show()

6.3 集成到Web应用

在Flask应用中集成天气功能非常简单:

from flask import Flask, jsonify import requests app = Flask(__name__) @app.route('/weather/<city_code>') def weather(city_code): try: data = requests.get(f'http://t.weather.itboy.net/api/weather/city/{city_code}').json() return jsonify({ 'temperature': data['data']['wendu'], 'humidity': data['data']['shidu'], 'condition': data['data']['forecast'][0]['type'] }) except Exception as e: return jsonify({'error': str(e)}), 500

7. 进阶技巧与注意事项

7.1 时区处理

天气数据中的时间戳可能使用UTC时间,需要转换为本地时区:

from datetime import datetime import pytz utc_time = datetime.strptime(api_data['time'], '%Y-%m-%d %H:%M:%S') local_time = utc_time.replace(tzinfo=pytz.utc).astimezone(pytz.timezone('Asia/Shanghai'))

7.2 多API备用方案

重要项目建议准备备用API,当主接口不可用时自动切换:

APIS = [ 'http://primary.api/weather', 'http://backup1.api/weather', 'http://backup2.api/weather' ] def get_weather_with_fallback(city_code): for api in APIS: try: response = requests.get(f'{api}/{city_code}', timeout=3) return response.json() except: continue raise Exception("所有天气API均不可用")

7.3 数据存储策略

对于需要历史天气数据的应用,建议设计合理的存储方案。这是我常用的MongoDB文档结构:

{ "city_code": "101010100", "date": "2023-05-01", "temperature": 22, "humidity": 0.45, "condition": "晴", "created_at": datetime.datetime.now() }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询