利用python爬取腾讯疫情实时播报数据,接着用pyecharts处理数据,生成相应的疫情分布图、疫情发展趋势图,最后利用pyqt打造一个GUI程序。
ps:如果不是老师要求,我基本不会写这么一篇博客,路过的就直接跳过吧。这篇博客只是等待老师的宠幸。(卑微咸鱼的自白)
emmmm!要用python开发系统,肯定要安装python开发环境了,直接百度python3 安装,有很多教程很详细,直接安装就好了。
pycharm是一个集成开发环境,可以直接到官网安装,有免费的社区版可以用,就是不知道社区版可不可以弄扩展工具,如果不可以的话,就得花钱买正版(自己想办法),安装成功后就可以使用了。
这个安装比较复杂,我建议直接在pycharm里面安装。具体步骤如下:
1、打开pycharm;
2、点击下图我圈红色的那个file
3、点击file后,可以看到红色圈着的setting,点击setting
5、点击setting,先找到圈黑色笔的,然后找到圈红色笔的
6、然后开始搜索pyqt5、pyqt5-tools、qtpy、pyqtWebengine、把这些通通安装
安装完以上工具差不多就可以配置了,步骤如下(接下来可能会遇到及其令你摸不着头脑的事儿)
1、打开pycharm;
2、点击菜单栏的file;
3、找到setting;
4、点击Tools,按照图片先找到黑色再点击红色的;
5、按照图片设置,name那一项随你填,知道这个扩展工具干啥的就行,program哪一个要找准位置,是你的可执行文件的路径,qtdesigner不用参数,后面两个的argument要填这个参数,具体看图片,参数在最后一张截图。路径一般都差不多,搜索pyqt安装教程一般都能找到。
6、安装完点击菜单栏的Tools,点击子菜单External Tools,点击qtdesigner,能成功打开就好了,一般会遇到说是无法驱动qt的程序,对于这个问题直接百度答案也是鱼龙混杂,我的解决方法是参照一篇文章链接: link.
整体思路是这样子的,点击按钮,触发相应的爬虫程序,爬取数据,生成html,然后利用webview渲染出来,(这个项目我同时又拿去交给另一个要求我们开发qt项目的老师了。)
首先,如果你工具安装了,也同时配置了,那么你可以在pycharm中打开qtdesigner,进行页面设计,要怎么设计就怎么设计噢,随你个人喜欢,因为qtdesigner已经移除了对web组件的支持,所以可以随便弄个组件代替它来定位,到时 修改就好了。
这里我附上我自己设计的,之所以多了一个关闭按钮,主要是因为我后期想要把窗口的标题栏去掉,之所以要隐藏标题栏是因为我不会重写mainwindow类,而且qdarkstyle不支持美化标题栏。
做完之后保存到python项目里,会发现项目里多了一个ui文件。
接下来,选中ui文件,点击external tools,点击pyUIC,这时就会生成一个py文件了,这个文件实现了界面的效果,当然你现在还不可以使用。
这时候呢,你可以开始创建启动页面的py文件了,首先新建一个python文件,命名为Call+你ui文件保存的名字,然后,创建一个类,具体看代码:
import 由ui文件生成的py文件
import sys
class MyMainWin(QMainWindow, Ui_MainWindow):
flag = 0
def __init__(self, parent=None):
super(MyMainWin, self).__init__(parent)
self.setupUi(self)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = MyMainWin()
win.show()
sys.exit(app.exec_())
然后运行程序就可以看到你之前设计的界面,这个时候你的程序还是没什么美化的,如果你想自己写样式,可以网上搜索qstylesheet,自己美化,或者可以去网上下载开源的qdarkstyle样式表美化,下载完把qstyledark文件夹复制到项目里,然后修改代码为:
import sys
import qdarkstyle
import 由ui文件生成的py文件
class MyMainWin(QMainWindow, Ui_MainWindow):
flag = 0
def __init__(self, parent=None):
super(MyMainWin, self).__init__(parent)
self.setupUi(self)
if __name__ == "__main__":
app = QApplication(sys.argv)
# app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
win = MyMainWin()
# 加载样式
win.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
win.show()
sys.exit(app.exec_())
这时候运行就可以看到美化后的界面了。我实在太懒了不像放图了。
接下来我们要把前面有ui文件生成的py文件修改了,注意一旦生成后就不要随意使用qt设计师模式修改页面了,否则代码又会重新生成的。
找到你想替换成web组件的组件,讲组件修改为web组件。这样运行程序就会得到一个浏览器窗口了。
以上开发出了界面,但是各种功能按钮都是没有用的,接下来你要做的就是做好逻辑功能的开发,废话不说,代码都写得很详细,直接上了。
生成中国疫情分布图情况的代码
'''
作者:谢思凌
时间:2020/06/17
'''
# 导入请求发送模块
import requests
# 导入json模块
import json
# 导入 xlrd模块解析excel表格
import xlrd
# 导入pyecharts
from pyecharts import Map
# 导入datetime模块
import datetime
# 请求中国疫情数据链接
def creatMap():
# 获取当前时间
curr_time = datetime.datetime.now()
# 格式化时间
time_str = curr_time.strftime("%Y-%m-%d %H:%M:%S")
baseUrl = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5&callback=jQuery3410966110964980829_1592350653305&_=1592350653306'
# 获取当前链接返回的数据
chinaData = requests.get(baseUrl).text.replace('"{', '{').replace('}"}', '}}').replace('\\', '')
# 处理数据
chinaData = chinaData[chinaData.index("{"):-1]
# 将当前的json字符串转化为python字典
baseData = json.loads(chinaData)
# 保存省份的名称
provinceNameList = []
# 保存各个省份的确诊数据
provinceConfirmDataList = []
# 从数据中提取各个省份的疫情信息
provinceList = baseData["data"]["areaTree"][0]["children"]
for province in provinceList:
provinceNameList.append(province["name"])
provinceConfirmDataList.append(province["total"]["confirm"])
# 创建地图
map = Map(title="中国疫情分布图 "+time_str, width=800, height=400, title_color="red")
# 添加地图相关参数
map.add("中国地图", provinceNameList, provinceConfirmDataList, maptype="china",
visual_range=[1, 1000], visual_text_color="#000", is_visualmap=True)
# 显示地图配置参数
#map.show_config()
# 渲染地图
map.render(path="output/中国疫情分布图.html")
# print("已生成,请移步output文件夹查看")
生成中国疫情发展趋势图的代码
# 导入json
import json
# 导入request
import requests
# 导入pyecharts模块的Line
from pyecharts import Line
# 导入datetime模块
import datetime
# 创建折线图
def creatAnalysisMap():
# 获取时间
curr_time = datetime.datetime.now()
time_str = curr_time.strftime("%Y-%m-%d %H:%M:%S")
# 创建折线图
line = Line("中国疫情发展趋势图 "+time_str, width=1200, height=600)
# 请求中国疫情数据链接
baseUrl = "https://view.inews.qq.com/g2/getOnsInfo?name=disease_other&callback=jQuery34105560710307785617_1592363143544&_=1592363143545"
# 当前请求链接返回的数据
chinaData = requests.get(baseUrl).text.replace('"{', '{').replace('}"}', '}}').replace('\\', '')
# 处理数据
chinaData = chinaData[chinaData.index("{"):-1]
# 将当前的json字符串转换成python的字典
baseData = json.loads(chinaData)
# 保存疫情属性列表
attrList = ["累计确诊", "现有疑似", "现有确诊", "现有重症", "境外输入"]
# 日期列表
dateList = []
# 累计确诊列表
confirmList = []
# 现有疑似列表
suspectList = []
# 现有确诊列表
nowConfirmList = []
# 现有重症列表
nowSevereList = []
# 境外输入列表
importedCaseList = []
# 解析数据
for item in baseData["data"]["chinaDayList"]:
# 追加日期
dateList.append(item["date"])
# 追加累计确诊列表
confirmList.append(item["confirm"])
# 追加现有疑似列表
suspectList.append(item["suspect"])
# 追加现有确诊列表
nowConfirmList.append(item["nowConfirm"])
# 追加现有重症列表
nowSevereList.append(item["nowSevere"])
# 追加境外输入列表
importedCaseList.append(item["importedCase"])
# 添加各个属性直线图
line.add("累计确诊", dateList, confirmList, mark_point=['max'])
line.add("现有疑似", dateList, suspectList, mark_point=['max'])
line.add("现有确诊", dateList, nowConfirmList, mark_point=['max'])
line.add("现有重症", dateList, nowSevereList, mark_point=['max'])
line.add("境外输入", dateList, importedCaseList, mark_point=['max'])
# 显示图形参数
# line.show_config()
line.render(path="output/中国疫情发展趋势图.html")
print("已生成,请移步output文件夹查看")
生成世界疫情分布图的代码
'''
作者:谢思凌
时间:2020/06/17
'''
# 导入请求发送模块
import requests
# 导入json模块
import json
# 导入 xlrd模块解析excel表格
import xlrd
# 导入pyecharts
from pyecharts import Map
# 导入时间模块
import datetime
def creatMap():
# 获取当前时间
curr_time = datetime.datetime.now()
time_str = curr_time.strftime("%Y-%m-%d %H:%M:%S")
# 请求海外各国疫情数据链接
baseUrl = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_foreign&callback=jQuery341035828799971754144_1592295771001&_=1592295771002'
# 获取当前链接返回的数据
worldData = requests.get(baseUrl).text.replace('"{', '{').replace('}"}', '}}').replace('\\', '')
# 处理数据
worldData = worldData[worldData.index("{"):-1]
# 将当前的json字符串转化为python字典
baseData = json.loads(worldData)
# 打开excel文件获取数据
excelData = xlrd.open_workbook("世界各国中英文对照表.xlsx")
# 通过索引顺序获取当前sheet表
table = excelData.sheet_by_index(0)
# 获取行数
rows = table.nrows
# 创建国家中英文对照字典
countryDict = {}
# 循环获取中英文国家名称的键值对(字典)
for i in range(rows):
countryDict[table.row_values(i)[1]] = table.row_values(i)[0]
# 保存英文国家名称列表
englishCountryNameList = []
# 保存各个国家的确诊数据
countryConfirmDataList = []
# 获取每个国家的名称和当前累计确诊人数
for country in baseData["data"]["foreignList"]:
if country["name"] in countryDict:
englishCountryNameList.append(countryDict[country["name"]])
countryConfirmDataList.append(country["confirm"])
# 创建地图
map = Map(title="世界疫情分布图 "+time_str, width=800, height=400, title_color="red")
# 添加世界地图相关参数
map.add("世界地图", englishCountryNameList, countryConfirmDataList, maptype="world",
visual_range=[1, 10000], visual_text_color="#000", is_visualmap=True)
# 显示地图配置参数
# map.show_config()
# 渲染地图
map.render(path="output/世界疫情分布图.html")
#print("已生成,请移步output文件夹查看")
查询世界任一国家疫情发展趋势图代码
# 导入json模块
import json
# 导入requests模块
import requests
# 导入pyecharts模块中的Line
from pyecharts import Line
# 导入datetime模块
import datetime
def creatAnalysisMap(country):
# 获取当前时间
curr_time = datetime.datetime.now()
# 格式化当前时间
time_str = curr_time.strftime("%Y-%m-%d %H:%M:%S")
# 创建折线图
line = Line(country+"疫情发展趋势图 "+time_str, width=800, height=400)
# 参与统计国家的列表
# countryNameList = ["美国", "意大利", "西班牙", "伊朗", "法国", "德国", "韩国", "日本本土", "加拿大"]
# 定义各个国家获取链接模板
url = "https://api.inews.qq.com/newsqa/v1/automation/foreign/daily/list?country="+country+"&"
# 循环遍历各个国家获取数据
basedata = requests.get(url).text
data = json.loads(basedata)
# 保存日期列表
dateList = []
# 保存每日确诊人数
confirmList = []
# 保存治愈人数
healList = []
# 保存死亡人数
deadList = []
for item in data["data"]:
# 追加日期
dateList.append(item["date"])
# 追加确诊人数
confirmList.append(item["confirm"])
# 追加治愈人数
healList.append(item["heal"])
# 追加死亡人数
deadList.append(item["dead"])
# 添加各国折线图
line.add("确诊人数", dateList, confirmList, mark_point=['max'])
line.add("治愈人数", dateList, healList, mark_point=['max'])
line.add("死亡人数", dateList, deadList, mark_point=['max'])
# 显示图形参数
# line.show_config()
line.render(path="output/"+country+"疫情发展趋势图.html")
# print("已生成,请移步output文件夹查看")
前后端写完了,接下来我们来看前端与后端如何绑定在一起,在qt中,通过信号与槽机制来实现前后端的绑定,为每一个功能键或按钮绑定一个信号与槽函数,通过发送信号,来执行槽函数,实现相应功能,具体看代码:
from MainWin import Ui_MainWindow
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
import qdarkstyle
import ChinaAnalysis, ChinaMap, WorldAnalysis, WorldMap
class MyMainWin(QMainWindow, Ui_MainWindow):
flag = 0
def __init__(self, parent=None):
super(MyMainWin, self).__init__(parent)
self.setupUi(self)
# 初始化页面数据
url = r'D:/Document/code/python/PyQt_Diease_RealTime/output/中国疫情分布图.html'
self.browser.load(QUrl(url))
# 为菜单键查看中国疫情情况信号绑定槽函数
self.China_diease.triggered.connect(self.view_Chain)
# 为菜单键查看世界疫情情况信号绑定槽函数
self.World_diease.triggered.connect(self.view_World)
# 为菜单键查询国家疫情情况信号绑定槽函数
self.Query_country_diease.triggered.connect(self.query_Country)
# 为疫情分布图按钮信号绑定槽函数
self.pushButton.clicked.connect(self.btn_diease)
# 为疫情趋势图按钮信号绑定槽函数
self.pushButton_2.clicked.connect(self.btn2_diease)
# 为更新按钮信号绑定槽函数
self.pushButton_3.clicked.connect(self.upadate_diease)
# 查看中国疫情情况槽函数
def view_Chain(self):
self.flag = 1
# 创建中国疫情分布图
ChinaMap.creatMap()
# 创建中国疫情发展趋势图
ChinaAnalysis.creatAnalysisMap()
# 渲染中国疫情分布图
url = r'D:/Document/code/python/PyQt_Diease_RealTime/output/中国疫情分布图.html'
self.browser.load(QUrl(url))
# 查看世界疫情情况槽函数
def view_World(self):
self.flag = 2
WorldMap.creatMap()
url = r'D:/Document/code/python/PyQt_Diease_RealTime/output/世界疫情分布图.html'
self.browser.load(QUrl(url))
# 查询任意国家疫情情况槽函数
def query_Country(self):
# 调用输入对话框,获取待查询国家名称
countryName, ok = QInputDialog.getText(self, "查询", "输入国家名字")
if ok:
WorldAnalysis.creatAnalysisMap(countryName)
url = r'D:/Document/code/python/PyQt_Diease_RealTime/output/'+countryName+'疫情发展趋势图.html'
self.browser.load(QUrl(url))
# 更新按钮槽函数
def upadate_diease(self):
# flag = 1 代表查看了中国的情况,接下来的分布图、趋势图的更新等都要渲染中国的情况
if self.flag == 1:
self.view_Chain()
# 弹出提示框
reply = QMessageBox.information(self, "提示", "更新成功", QMessageBox.Yes, QMessageBox.Yes)
# flag = 2 代表查看了世界的情况,接下来的趋势图更新要渲染世界的情况
if self.flag == 2:
self.view_World()
# 弹出提示框
reply = QMessageBox.information(self, "提示", "更新成功", QMessageBox.Yes, QMessageBox.Yes)
# 疫情分布图按钮槽函数
def btn_diease(self):
# flag = 1 代表查看了中国的情况,接下来要渲染中国疫情分布图情况
if self.flag == 1:
ChinaMap.creatMap()
url = r'D:/Document/code/python/PyQt_Diease_RealTime/output/中国疫情分布图.html'
self.browser.load(QUrl(url))
# flag = 2 代表查看了世界的情况,接下来要渲染世界疫情分布图情况
if self.flag == 2:
WorldMap.creatMap()
url = r'D:/Document/code/python/PyQt_Diease_RealTime/output/世界疫情分布图.html'
self.browser.load(QUrl(url))
# 疫情趋势图按钮槽函数
def btn2_diease(self):
url = r'D:/Document/code/python/PyQt_Diease_RealTime/output/中国疫情发展趋势图.html'
self.browser.load(QUrl(url))
if __name__ == "__main__":
app = QApplication(sys.argv)
# app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
win = MyMainWin()
# 加载样式
win.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
win.show()
sys.exit(app.exec_())
活在当下,不为未来担忧!这个学期写实验报告总结写得快吐了。