自动化天气查询工具(API调用)完全指南

天气数据是日常生活中经常需要查询的信息之一。本教程将介绍如何使用Python编写一个自动化天气查询工具,通过调用开放的天气API获取实时天气数据。这个工具适合完全不懂编程的新手学习,将从最基础的环境搭建讲起,逐步实现完整的天气查询功能。

环境准备

在开始编写代码之前,需要确保计算机上已经安装了Python环境。Python是一种简单易学的编程语言,非常适合新手入门。可以从Python官网下载最新版本,安装过程保持默认选项即可。

安装完成后,打开命令提示符或终端,输入python --version检查是否安装成功。为了管理项目依赖,还需要安装pip工具,它是Python的包管理器。多数情况下,Python安装时会自动包含pip。

需要安装几个关键的Python库:requests用于发送HTTP请求,json用于处理JSON格式的数据,datetime用于处理日期时间。这些库可以通过以下命令安装:

pip install requests

获取API密钥

大多数天气数据服务都需要API密钥才能访问。OpenWeatherMap是一个提供免费天气API的服务,注册账户后可以获得免费的API密钥。访问OpenWeatherMap官网,完成注册流程,在个人仪表板中可以找到API密钥。

免费版的API有一定的调用限制,但对于个人学习和测试完全够用。API密钥是一个长字符串,需要妥善保管,不要直接暴露在公开的代码中。

基本API调用

理解HTTP请求是使用API的核心。API通常通过HTTP协议提供数据,最常见的请求方式是GET。请求需要包含必要的参数,如位置信息、API密钥等。

使用requests库发送GET请求非常简单:

import requestsapi_key = "你的API密钥"
city = "北京"
url = f"http://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}"response = requests.get(url)
data = response.json()

这段代码构造了一个API请求URL,包含城市名称和API密钥两个参数。requests.get()发送请求后,返回的响应可以通过.json()方法转换为Python字典。

解析天气数据

API返回的JSON数据包含丰富的天气信息,需要从中提取关键数据展示给用户。典型的天气数据包括温度、湿度、天气状况、风速等。

温度数据默认使用开尔文单位,需要转换为更常用的摄氏度:

temperature = data["main"]["temp"] - 273.15
humidity = data["main"]["humidity"]
weather_desc = data["weather"][0]["description"]
wind_speed = data["wind"]["speed"]

数据解析后可以格式化为更友好的输出:

print(f"当前天气: {weather_desc}")
print(f"温度: {temperature:.1f}°C")
print(f"湿度: {humidity}%")
print(f"风速: {wind_speed}m/s")

添加用户交互

基本的天气查询功能实现后,可以增加用户交互使工具更实用。使用input函数让用户输入要查询的城市:

city = input("请输入要查询的城市名称: ")

为了处理用户输入可能导致的错误,如城市不存在或API请求失败,需要添加异常处理:

try:response = requests.get(url)response.raise_for_status()data = response.json()
except requests.exceptions.RequestException as e:print(f"获取天气数据失败: {e}")exit()

美化输出格式

原始的控制台输出比较简陋,可以通过添加分隔线和颜色来改善显示效果。虽然控制台本身不支持富文本,但可以使用ANSI颜色代码:

print("\033[1;36m====== 天气查询结果 ======\033[0m")
print(f"\033[1;33m城市: \033[0m{city}")
print(f"\033[1;33m天气状况: \033[0m{weather_desc}")
print(f"\033[1;33m温度: \033[0m{temperature:.1f}°C")

扩展功能

基础功能完成后,可以考虑添加更多实用功能。例如,查询多个城市的天气、保存查询历史、设置温度单位等。

多城市查询可以通过循环实现:

cities = ["北京", "上海", "广州"]
for city in cities:# 查询每个城市的天气...

添加历史记录功能需要将每次查询的结果保存到文件或数据库中。简单的文件存储实现:

import json
from datetime import datetimehistory = {"city": city,"temperature": temperature,"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}with open("weather_history.json", "a") as f:f.write(json.dumps(history) + "\n")

完整代码实现

将上述所有功能整合,形成完整的天气查询工具。代码结构清晰,包含错误处理、用户交互和数据持久化等完整功能。

import requests
import json
from datetime import datetimedef get_weather(api_key, city):url = f"http://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}"try:response = requests.get(url)response.raise_for_status()return response.json()except requests.exceptions.RequestException as e:print(f"获取天气数据失败: {e}")return Nonedef display_weather(data, city):if not data:returntemperature = data["main"]["temp"] - 273.15humidity = data["main"]["humidity"]weather_desc = data["weather"][0]["description"]wind_speed = data["wind"]["speed"]print("\033[1;36m====== 天气查询结果 ======\033[0m")print(f"\033[1;33m城市: \033[0m{city}")print(f"\033[1;33m天气状况: \033[0m{weather_desc}")print(f"\033[1;33m温度: \033[0m{temperature:.1f}°C")print(f"\033[1;33m湿度: \033[0m{humidity}%")print(f"\033[1;33m风速: \033[0m{wind_speed}m/s")def save_history(city, temperature):history = {"city": city,"temperature": temperature,"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")}with open("weather_history.json", "a") as f:f.write(json.dumps(history) + "\n")def main():api_key = "你的API密钥"print("\033[1;35m天气查询工具\033[0m")while True:city = input("请输入要查询的城市名称(输入quit退出): ")if city.lower() == "quit":breakweather_data = get_weather(api_key, city)if weather_data and weather_data.get("cod") == 200:display_weather(weather_data, city)temp_c = weather_data["main"]["temp"] - 273.15save_history(city, temp_c)else:print("无法获取该城市的天气数据,请检查城市名称是否正确")if __name__ == "__main__":main()

部署和使用

完成代码编写后,可以将其保存为.py文件(如weather_app.py),通过命令行运行:

python weather_app.py

程序启动后会提示输入城市名称,输入后即可查看该城市的实时天气信息。查询历史会自动保存到同目录下的weather_history.json文件中。

进阶学习方向

掌握了基础天气查询工具的开发后,可以考虑以下进阶方向:

  1. 开发图形用户界面(GUI),使用Tkinter或PyQt等库
  2. 将应用部署为Web服务,使用Flask或Django框架
  3. 添加天气预报功能,查询多天预报数据
  4. 实现异常天气提醒功能
  5. 开发手机APP版本,使用Kivy等跨平台框架
完整源码
import requests
import json
from datetime import datetimedef get_weather(api_key, city):"""获取指定城市的天气数据"""base_url = "http://api.openweathermap.org/data/2.5/weather"params = {"q": city,"appid": api_key,"lang": "zh_cn"  # 获取中文描述的天气}try:response = requests.get(base_url, params=params)response.raise_for_status()  # 检查请求是否成功return response.json()except requests.exceptions.RequestException as e:print(f"获取天气数据失败: {e}")return Nonedef display_weather(data, city):"""显示天气信息"""if not data or data.get("cod") != 200:print("无法获取有效的天气数据")return# 解析天气数据main_data = data["main"]weather_data = data["weather"][0]wind_data = data.get("wind", {})# 单位转换和数据处理temperature = main_data["temp"] - 273.15  # 开尔文转摄氏度feels_like = main_data["feels_like"] - 273.15temp_min = main_data["temp_min"] - 273.15temp_max = main_data["temp_max"] - 273.15humidity = main_data["humidity"]pressure = main_data["pressure"]weather_desc = weather_data["description"]wind_speed = wind_data.get("speed", 0)wind_deg = wind_data.get("deg", 0)clouds = data.get("clouds", {}).get("all", 0)visibility = data.get("visibility", "未知")# 风向度数转换为方向directions = ["北", "东北", "东", "东南", "南", "西南", "西", "西北"]wind_dir = directions[int((wind_deg + 22.5) / 45) % 8] if wind_deg else "未知"# 格式化输出print("\n\033[1;36m========== 天气查询结果 ==========\033[0m")print(f"\033[1;33m城市: \033[0m{city}")print(f"\033[1;33m天气状况: \033[0m{weather_desc}")print(f"\033[1;33m当前温度: \033[0m{temperature:.1f}°C (体感{feels_like:.1f}°C)")print(f"\033[1;33m温度范围: \033[0m{temp_min:.1f}°C ~ {temp_max:.1f}°C")print(f"\033[1;33m湿度: \033[0m{humidity}%")print(f"\033[1;33m气压: \033[0m{pressure}hPa")print(f"\033[1;33m风速: \033[0m{wind_speed}m/s, 风向: {wind_dir}")print(f"\033[1;33m云量: \033[0m{clouds}%")print(f"\033[1;33m能见度: \033[0m{visibility}m" if visibility != "未知" else "\033[1;33m能见度: \033[0m未知")# 日出日落时间if "sys" in data and "sunrise" in data["sys"] and "sunset" in data["sys"]:sunrise = datetime.fromtimestamp(data["sys"]["sunrise"]).strftime("%H:%M:%S")sunset = datetime.fromtimestamp(data["sys"]["sunset"]).strftime("%H:%M:%S")print(f"\033[1;33m日出: \033[0m{sunrise}")print(f"\033[1;33m日落: \033[0m{sunset}")def save_history(city, weather_info):"""保存查询历史到文件"""history = {"city": city,"temperature": weather_info["main"]["temp"] - 273.15,"weather": weather_info["weather"][0]["description"],"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")}try:with open("weather_history.json", "a", encoding="utf-8") as f:f.write(json.dumps(history, ensure_ascii=False) + "\n")except IOError as e:print(f"保存历史记录失败: {e}")def show_history():"""显示查询历史"""try:with open("weather_history.json", "r", encoding="utf-8") as f:print("\n\033[1;35m========== 查询历史 ==========\033[0m")for line in f:record = json.loads(line.strip())print(f"{record['time']} - {record['city']}: {record['temperature']:.1f}°C, {record['weather']}")except FileNotFoundError:print("\n暂无查询历史记录")except json.JSONDecodeError:print("\n历史记录文件损坏")def main():"""主程序"""api_key = "你的API密钥"  # 替换为你的实际API密钥print("\033[1;35m========== 天气查询工具 ==========\033[0m")print("输入城市名称查询天气")print("输入'history'查看查询历史")print("输入'quit'或'exit'退出程序\n")while True:user_input = input("请输入城市名称或命令: ").strip()if user_input.lower() in ("quit", "exit"):print("感谢使用天气查询工具,再见!")breakif user_input.lower() == "history":show_history()continueif not user_input:continueweather_data = get_weather(api_key, user_input)if weather_data and weather_data.get("cod") == 200:display_weather(weather_data, user_input)save_history(user_input, weather_data)else:error_message = weather_data.get("message", "未知错误") if weather_data else "请求失败"print(f"无法获取天气数据: {error_message}")if __name__ == "__main__":main()

这个完整版本增加了更多天气细节的显示,包括温度(当前/最高/最低)、湿度、风速、气压、能见度、日出日落时间等全面信息。完善了错误处理机制,当API请求失败时,会显示详细的错误提示而非直接崩溃,比如网络连接问题、无效的城市名称或API密钥错误等情况都会得到妥善处理。

特别提供了贴心的查询历史功能,系统会自动记录用户最近搜索的10个城市,方便快速回溯查看。历史记录会以时间倒序排列,并支持一键清除功能。为了优化用户体验,代码还实现了本地缓存机制,避免频繁请求API。

使用前请注意:

  1. 请确保将代码中的"你的API密钥"替换为实际的OpenWeatherMap API密钥
  2. 建议在开发环境下测试后再部署到生产环境
  3. API有调用频率限制,免费版每分钟60次,每小时1000次
  4. 如需获取历史天气数据,需要订阅付费计划

示例请求格式:

api_key = "your_actual_api_key_here"  # 替换为真实密钥
city_name = "Beijing"
url = f"http://api.openweathermap.org/data/2.5/weather?q={city_name}&appid={api_key}&units=metric"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/91865.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/91865.shtml
英文地址,请注明出处:http://en.pswp.cn/web/91865.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【ROS2】常用命令

1、目录结构在 ROS 2 包中,launch、urdf、rviz(通常指 RViz 配置文件)、config 等文件夹应直接放在包的根目录下(与 robot_arm/ Python 模块目录同级)。这是 ROS 2 社区的通用约定,便于工具(如 …

基础组件(三):mysql连接池

文章目录一、MySQL连接池设计1. 连接池解决了什么问题?连接池的作用 (好处)为什么不创建多条连接而用连接池2. 同步和异步连接池的区别同步连接池(场景局限,应用服务器启动时初始化资源)异步连接池&#xf…

FI文件包含漏洞

本地文件包含(LFI)文件包含开发人员将可重复使用的内容写到单个文件中,使用时直接调用此文件,无需再次编写,这种调用文件的过程一般被称为文件包含。这样编写代码能减少代码冗余,降低代码后期维护难度&…

rapidocr_web v1.0.0发布了

建立RapidOCRWeb独立仓库 终于将web这块代码移了出来,成立了独立仓库RapidOCRWeb (https://github.com/RapidAI/RapidOCRWeb )。这样以来,RapidOCR仓库下的各个衍生项目均有自己的独立仓库,可以单独控制发版和维护。这也算是为RapidOCR减负了…

Arduino IDE离线安装ESP8266板管理工具

文章目录概要官网地址开发板管理地址安装ESP8266开发板支持离线安装额外记录NODE启动服务概要 Arduino IDE离线安装ESP8266板管理工具&#xff0c;在线安装因为网络或者https的问题不能安装 官网地址 Adruino&#xff1a;https://www.arduino.cc/ ESP8266项目&#xff1a;<…

两款免费数据恢复软件介绍,Win/Mac均可用

数据已成为我们生活与工作中不可或缺的重要组成部分。无论是珍贵的家庭照片、关键的工作文档&#xff0c;还是重要的学习资料&#xff0c;都以数据的形式存储在各类设备中。然而&#xff0c;数据丢失的情况却时常发生&#xff0c;可能是误操作删除&#xff0c;可能是设备意外损…

Java开发中敏感信息加密存储全解析:筑牢数据安全防线

Java开发中敏感信息加密存储全解析&#xff1a;筑牢数据安全防线 一、引言 1.1 敏感信息存储的现状与挑战 在数字化时代&#xff0c;数据已然成为企业和组织的核心资产之一&#xff0c;而敏感信息的存储更是重中之重。从日常的用户登录密码、身份证号码&#xff0c;到金融领域…

list的使用和模拟

(一)list的了解 (1)简单了解 list的文档介绍 list是基于双向链表的序列式容器&#xff0c;支持双向迭代和任意位置的常数时间插入删除&#xff0c;相比 array、vector 等容器在这类操作上更高效&#xff0c;但不支持随机访问&#xff08;访问需线性遍历&#xff09;且因额外…

Docker 初学者需要了解的几个知识点 (五):建容器需要进一步了解的概念

之前在《Docker 初学者需要了解的几个知识点》几篇文章里&#xff0c;我们梳理了 Docker 的核心概念&#xff08;如镜像、容器、网络等&#xff09;&#xff0c;但在实际搭建 ThinkPHP 容器环境时&#xff0c;又遇到了一些更具体的术语和配置场景。这些内容和实操结合紧密&…

【数据结构】栈的顺序存储(整型栈、字符栈)

【数据结构】栈的顺序存储&#xff08;整型栈、字符栈&#xff09;一、栈的结构定义二、字符栈的初始化、入栈、出栈、判断是否栈为空、获取栈顶元素、获取栈的当前元素个数等操作三、整型栈的初始化、入栈、出栈、判断是否栈为空、获取栈顶元素、获取栈的当前元素个数等操作一…

【大模型实战】向量数据库实战 - Chroma Milvus

在 RAG&#xff08;检索增强生成&#xff09;场景中&#xff0c;非结构化数据&#xff08;文本、图像等&#xff09;的高效检索是核心需求。传统关系型数据库难以胜任&#xff0c;而向量数据库通过将数据转化为向量、基于相似度快速匹配&#xff0c;成为 RAG 的关键支撑。本文聚…

pytorch程序语句固定开销分析

深入探索PyTorch与Python的性能微观世界&#xff1a;量化基础操作的固定开销 在深度学习的性能优化工作中&#xff0c;开发者通常将目光聚焦于模型结构、算法效率和并行计算策略。然而&#xff0c;在这些宏观优化的背后&#xff0c;构成我们代码的每一条基础语句——无论是PyTo…

ABP VNext + CloudEvents:事件驱动微服务互操作性

ABP VNext CloudEvents&#xff1a;事件驱动微服务互操作性 &#x1f680; &#x1f4da; 目录ABP VNext CloudEvents&#xff1a;事件驱动微服务互操作性 &#x1f680;一、引言 ✨☁️ TL;DR&#x1f4da; 背景与动机&#x1f3d7;️ 整体架构图二、环境准备与依赖安装 &am…

软件测试测评公司关于HTTP安全头配置与测试?

浏览器和服务器之间那几行看不见的HTTP安全头配置&#xff0c;往往是抵御网络攻击的关键防线。作为软件测试测评公司&#xff0c;我们发现超过六成的高危漏洞源于安全头缺失或误配。别小看这些响应头&#xff0c;它们能直接掐断跨站脚本、点击劫持、数据嗅探的攻击路径。五条命…

Mysql集成技术

目录 mysql的编译安装与部署 1.编译安装mysql 2.部署mysql mysql主从复制 什么是mysql主从复制&#xff1f; 1.配置master 2.配置slave 3.存在数据时添加slave2 4.GTID模式 什么是GTID模式&#xff1f; 配置GTID 5.延迟复制 6.慢查询日志 核心作用 开启慢查询日志…

《MySQL进阶核心技术剖析(一): 存储引擎》

目录 一、存储引擎 1.1 MySQL体系结构 1.2 存储引擎介绍 1). 建表时指定存储引擎 2). 查询当前数据库支持的存储引擎 1.3 存储引擎特点 1.3.1 InnoDB 1.3.2 MyISAM 1.3.3 Memory 1.3.4 区别及特点 1.4 存储引擎选择 一、存储引擎 1.1 MySQL体系结构 1). 连接层 最上…

sqli-labs:Less-26关卡详细解析

1. 思路&#x1f680; 本关的SQL语句为&#xff1a; $sql"SELECT * FROM users WHERE id$id LIMIT 0,1";注入类型&#xff1a;字符串型&#xff08;单引号包裹&#xff09;、GET操作提示&#xff1a;参数需以闭合关键参数&#xff1a;id php输出语句的部分代码&am…

Spring Boot 的事务注解 @Transactional 失效的几种情况

开发中我们经常会用到 Spring Boot 的事务注解&#xff0c;为含有多种操作的方法添加事务&#xff0c;做到如果某一个环节出错&#xff0c;全部回滚的效果。但是在开发中可能会因为不了解事务机制&#xff0c;而导致我们的方法使用了 Transactional 注解但是没有生效的情况&…

#C语言——刷题攻略:牛客编程入门训练(四):运算

&#x1f31f;菜鸟主页&#xff1a;晨非辰的主页 &#x1f440;学习专栏&#xff1a;《C语言刷题合集》 &#x1f4aa;学习阶段&#xff1a;C语言方向初学者 ⏳名言欣赏&#xff1a;"代码行数决定你的下限&#xff0c;算法思维决定你的上限。" 目录 1. BC25 牛牛买电…

阻抗分析中的软件解调计算

接上篇 重温无功功率测量-CSDN博客 已知被测阻抗两端电压与流过 通过两个ADC同步采集到。 激励频率10k, 采样率1M, 每周期100个点 关键是:采样率除以激励频率, 得是4的倍数... 所以ADC不能自由运行, 得用一个timer来触发. 因为要进行同相分量正交分量计算。 1&#xff1a;直…