返回介绍

14.5 项目:取得当前的天气数据

发布于 2024-01-22 21:44:06 字数 4472 浏览 0 评论 0 收藏 0

检查天气似乎相当简单:打开Web浏览器,点击地址栏,输入天气网站的URL(或搜索一个,然后点击链接),等待页面加载,跳过所有的广告等。

其实,如果有一个程序,下载今后几天的天气预报,并以纯文本打印出来,就可以跳过很多无聊的步骤。该程序利用第11章介绍的requests模块,从网站下载数据。

总的来说,该程序将执行以下操作:

· 从命令行读取请求的位置。

· 从OpenWeatherMap.org下载JSON天气数据。

· 将JSON数据字符串转换成Python的数据结构。

· 打印今天和未来两天的天气。

因此,代码需要完成以下任务:

· 连接sys.argv中的字符串,得到位置。

· 调用requests.get(),下载天气数据。

· 调用json.loads(),将JSON数据转换为Python数据结构。

· 打印天气预报。

针对这个项目,打开一个新的文件编辑器窗口,并保存为quickWeather.py。

第1步:从命令行参数获取位置

该程序的输入来自命令行。让quickWeather.py看起来像这样:

#! python3
# quickWeather.py - Prints the weather for a location from the command line.

import json, requests, sys

# Compute location from command line arguments.
if len(sys.argv) <  2:
    print('Usage: quickWeather.py location')
    sys.exit()
location = ' '.join(sys.argv[1:])

# TODO: Download the JSON data from OpenWeatherMap.org's API.

# TODO: Load JSON data into a Python variable.

在Python中,命令行参数存储在sys.argv列表里。#!行和import语句之后,程序会检查是否有多个命令行参数(回想一下,sys.argv中至少有一个元素sys.argv[0],它包含了Python脚本的文件名)。如果该列表中只有一个元素,那么用户没有在命令行中提供位置,程序向用户提供“Usage(用法)”信息,然后结束。

命令行参数以空格分隔。命令行参数San Francisco, CA将使sys.argv中保存['quickWeather.py', 'San', 'Francisco,', 'CA']。因此,调用join()方法,将sys.argv中除第一个字符串以外的字符串连接起来。将连接的字符串存储在变量location中。

第2步:下载JSON数据

OpenWeatherMap.org提供了JSON格式的实时天气信息。你的程序只需要下载页面http://api.openweathermap.org/data/2.5/forecast/daily?q=< Location>&cnt=3,其中< Location>是想知道天气的城市。将以下代码添加到quickWeather.py中。

#! python3
# quickWeather.py - Prints the weather for a location from the command line.

--snip--

# Download the JSON data from OpenWeatherMap.org's API.
url ='http://api.openweathermap.org/data/2.5/forecast/daily?q=%s&cnt=3' % (location)
response = requests.get(url)
response.raise_for_status()

# TODO: Load JSON data into a Python variable.

我们从命令行参数中得到了 location。为了生成要访问的网址,我们利用%s占位符,将location中保存的字符串插入URL字符串的那个位置。结果保存在url中,并将url传入requests.get()。requests.get()调用返回一个Response对象,它可以通过调用raise_for_status()来检查错误。如果不发生异常,下载的文本将保存在response.text中。

第3步:加载JSON数据并打印天气

response.text成员变量保存了一个JSON格式数据的大字符串。要将它转换为Python值,就调用json.loads()函数。JSON数据会像这样:

{'city': {'coord': {'lat': 37.7771, 'lon': -122.42},
          'country': 'United States of America',
          'id': '5391959',
          'name': 'San Francisco',
          'population': 0},
 'cnt': 3,
 'cod': '200',
 'list': [{'clouds': 0,
           'deg': 233,
           'dt': 1402344000,
           'humidity': 58,
           'pressure': 1012.23,
           'speed': 1.96,
           'temp': {'day': 302.29,
                    'eve': 296.46,
                    'max': 302.29,
                    'min': 289.77,
                    'morn': 294.59,
                    'night': 289.77},
           'weather': [{'description': 'sky is clear',
                        'icon': '01d',
--snip--

可以将weatherData传入pprint.pprint,查看这个数据。你可能要查找http:// openweathermap.org/,找到关于这些字段含义的文档。例如,在线文档会告诉你,'day'后面的302.29是白天的开尔文温度,而不是摄氏或华氏温度。

你想要的天气描述在'main'和'description'之后。为了整齐地打印出来,在quickWeather.py中添加以下代码。

 #! python3
 # quickWeather.py - Prints the weather for a location from the command line.

 --snip--

 # Load JSON data into a Python variable.
 weatherData = json.loads(response.text)
 # Print weather descriptions.
❶ w = weatherData['list']
 print('Current weather in %s:' % (location))
 print(w[0]['weather'][0]['main'], '-', w[0]['weather'][0]['description'])
 print()
 print('Tomorrow:')
 print(w[1]['weather'][0]['main'], '-', w[1]['weather'][0]['description'])
 print()
 print('Day after tomorrow:')
 print(w[2]['weather'][0]['main'], '-', w[2]['weather'][0]['description'])

请注意,代码将weatherData['list']保存在变量w中,这将节省一些打字时间❶。可以用w[0]、w[1]和w[2]来取得今天、明天和后天天气的字典。这些字典都有'weather'键,其中包含一个列表值。你感兴趣的是第一个列表项(一个嵌套的字典,包含几个键),下标是0。这里,我们打印出保存在'main'和'description'键中的值,用连字符隔开。

如果用命令行参数quickWeather.py San Francisco, CA运行这个程序,输出看起来是这样的:

Current weather in San Francisco, CA:
Clear - sky is clear

Tomorrow:
Clouds - few clouds

Day after tomorrow:
Clear - sky is clear

(天气是我喜欢住在旧金山的原因之一!)

第4步:类似程序的想法

访问气象数据可以成为多种类型程序的基础。你可以创建类似程序,完成以下任务:

· 收集几个露营地点或远足路线的天气预报,看看哪一个天气最好。

· 如果需要将植物移到室内,安排一个程序定期检查天气并发送霜冻警报(第15章介绍了定时调度,第16章介绍了如何发送电子邮件)。

· 从多个站点获得气象数据,同时显示,或计算并显示多个天气预报的平均值。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文