1.获取天气数据
使用python获取天气数据有很多种方法,其中一种是通过爬虫方式,获取天气网站的HTML页面,然后使用BeautifulSoup等解析内容,还有就是通过天气预报网站提供的API接口,直接获取结构化的数据,省去了解析HTML的工作。所以本利采用第二种方法,使用中国天气网站提供的API。
中国天气官网:中国天气
获取天气数据要使用Requests库,如果没有安装,请使用pip进行安装。
pip install requests
该库有一个名为json的方法,当请求的接口放回的是json格式的数据时,直接使用该方法访问即可,不需要再使用Python标准库中的json库了。
2.获取不同城市的天气预报API
请求地址是:http://www.weather.com.cn/data/sk/城市代码.html (该地址已失效)
请求地址是:http://wthrcdn.etouch.cn/weather_mini?citykey=101270101 (101270101 是城市代码)
部分城市代码如下,完整的城市代码可自行百度查询。
城市名 | 城市代码 |
---|---|
北京 | 101010100 |
天津 | 101030100 |
上海 | 101020100 |
成都 | 101270101 |
部分返回参数列表如下:
名称 | 描述 |
---|---|
data | 消息根结点 |
city | 城市中文名 |
wendu | 温度 |
fengxiang | 风向 |
fengli | 风力中文 |
fengli | 风力 |
date | 日期 |
type | 天气类型 |
在浏览器地址输入http://wthrcdn.etouch.cn/weather_mini?citykey=101270101这个请求地址,浏览器就会返回成都最近几天的天气实时情况,该信息就是一个json格式的字符串,格式化后如下:
代码语言:javascript复制{
"data":{
"yesterday":{
"date":"9日星期一",
"high":"高温 23℃",
"fx":"南风",
"low":"低温 13℃",
"fl":"<![CDATA[1级]]>",
"type":"霾"
},
"city":"成都",
"forecast":[
{
"date":"10日星期二",
"high":"高温 21℃",
"fengli":"<![CDATA[1级]]>",
"low":"低温 15℃",
"fengxiang":"东南风",
"type":"多云"
},
{
"date":"11日星期三",
"high":"高温 20℃",
"fengli":"<![CDATA[1级]]>",
"low":"低温 15℃",
"fengxiang":"东北风",
"type":"多云"
},
{
"date":"12日星期四",
"high":"高温 20℃",
"fengli":"<![CDATA[1级]]>",
"low":"低温 15℃",
"fengxiang":"东北风",
"type":"多云"
},
{
"date":"13日星期五",
"high":"高温 19℃",
"fengli":"<![CDATA[1级]]>",
"low":"低温 14℃",
"fengxiang":"东北风",
"type":"阴"
},
{
"date":"14日星期六",
"high":"高温 19℃",
"fengli":"<![CDATA[1级]]>",
"low":"低温 14℃",
"fengxiang":"东北风",
"type":"阴"
}
],
"ganmao":"感冒低发期,天气舒适,请注意多吃蔬菜水果,多喝水哦。",
"wendu":"20"
},
"status":1000,
"desc":"OK"
}
示例代码:getWeatherInfo.py
代码语言:javascript复制# -*- coding: utf-8 -*-
import requests
req = requests.get('http://wthrcdn.etouch.cn/weather_mini?citykey=101270101')
req.encoding = 'utf-8'
print('返回结果: %s' % req.json())
data = req.json()['data']
print('城市: %s' % data['city'])
today = req.json()['data']['forecast'][0]
print('日期: %s' % today['date'])
print('天气: %s' % today['type'])
print('风向: %s' % today['fengxiang'])
print('温度: %s' % data['wendu'] " °C")
print('最高温度: %s' % today['high'])
print('最低温度: %s' % today['low'])
print('风力: %s' % today['fengli'][-5:-3])
print('感冒指数: %s' % data['ganmao'])
以上代码请求API,可以获取到天气数据:
3.界面实现
使用Qt Designer来设计天气预报窗口,如下图:
添加信号和槽函数:
4.将界面转化为.py文件
使用pyuic5命令将界面转为.py文件,转换后的Python文件名是WeatherWin.py。
pyuic5 -o WeatherWin.py WeatherWin.ui
转换后的完整代码如下:
代码语言:javascript复制# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'WeatherWin.ui'
#
# Created by: PyQt5 UI code generator 5.15.0
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(465, 327)
self.label = QtWidgets.QLabel(Form)
self.label.setGeometry(QtCore.QRect(10, 0, 71, 31))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(Form)
self.label_2.setGeometry(QtCore.QRect(51, 41, 24, 16))
self.label_2.setObjectName("label_2")
self.weatherComboBox = QtWidgets.QComboBox(Form)
self.weatherComboBox.setGeometry(QtCore.QRect(100, 40, 131, 20))
self.weatherComboBox.setEditable(False)
self.weatherComboBox.setObjectName("weatherComboBox")
self.weatherComboBox.addItem("")
self.weatherComboBox.addItem("")
self.weatherComboBox.addItem("")
self.weatherComboBox.addItem("")
self.resultText = QtWidgets.QTextEdit(Form)
self.resultText.setGeometry(QtCore.QRect(40, 70, 381, 181))
self.resultText.setObjectName("resultText")
self.queryBtn = QtWidgets.QPushButton(Form)
self.queryBtn.setGeometry(QtCore.QRect(100, 280, 75, 23))
self.queryBtn.setObjectName("queryBtn")
self.clearBtn = QtWidgets.QPushButton(Form)
self.clearBtn.setGeometry(QtCore.QRect(260, 280, 75, 23))
self.clearBtn.setObjectName("clearBtn")
self.retranslateUi(Form)
self.queryBtn.clicked.connect(Form.queryWeather)
self.clearBtn.clicked.connect(Form.clearResult)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.label.setText(_translate("Form", "查询城市天气"))
self.label_2.setText(_translate("Form", "城市"))
self.weatherComboBox.setCurrentText(_translate("Form", "成都"))
self.weatherComboBox.setItemText(0, _translate("Form", "成都"))
self.weatherComboBox.setItemText(1, _translate("Form", "北京"))
self.weatherComboBox.setItemText(2, _translate("Form", "上海"))
self.weatherComboBox.setItemText(3, _translate("Form", "天津"))
self.queryBtn.setText(_translate("Form", "查询"))
self.clearBtn.setText(_translate("Form", "清空"))
5.调用主窗口类
在主窗口类MainWindow中调用界面类Ui_Form,然后在主窗口类中添加查询天气和清空结果的业务逻辑代码,这样就使界面显示和业务逻辑分离了。 本例文件名为CallWeatherWin.py,在主窗口类中定义了两个槽函数queryWeather()和clearResult(),以便在界面文件WeatherWin.ui中定义的两个按钮(queryBtn和clearBtn)触发clicked信号与这两个槽函数进行绑定。完整代码如下:
代码语言:javascript复制# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from WeatherWin import Ui_Form
import requests
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
def queryWeather(self):
print('* queryWeather ')
cityName = self.ui.weatherComboBox.currentText()
cityCode = self.transCityName(cityName)
req = requests.get('http://wthrcdn.etouch.cn/weather_mini?citykey=' cityCode)
req.encoding = 'utf-8'
print(req.json())
data = req.json()['data']
today = req.json()['data']['forecast'][0]
msg1 = '城市: %s' % data['city'] 'n'
msg2 = '日期: %s' % today['date'] 'n'
msg3 = '天气: %s' % today['type'] 'n'
msg4 = '风向: %s' % today['fengxiang'] 'n'
msg5 = '温度: %s' % data['wendu'] " °C" 'n'
msg6 = '最高温度: %s' % today['high'] 'n'
msg7 = '最低温度: %s' % today['low'] 'n'
msg8 = '风力: %s' % today['fengli'][-5:-3] 'n'
msg9 = '感冒指数: %s' % data['ganmao'] 'n'
result = msg1 msg2 msg3 msg4 msg5 msg6 msg7 msg8 msg9
self.ui.resultText.setText(result)
def transCityName(self, cityName):
cityCode = ''
if cityName == '北京':
cityCode = '101010100'
elif cityName == '天津':
cityCode = '101030100'
elif cityName == '上海':
cityCode = '101020100'
elif cityName == '成都':
cityCode = '101270101'
return cityCode
def clearResult(self):
print('* clearResult ')
self.ui.resultText.clear()
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
效果图: