ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python天气数据可视化平台:MySQL+Flask+Echarts爬虫联调

Python天气数据可视化平台:MySQL+Flask+Echarts爬虫联调 简介《基于Python的天气数据可视化平台》是一份完整的毕业设计论文文档面向计算机、软件工程与云计算等专业需要完成课程设计或毕业设计的学生适合以数据爬取与可视化展示为选题的读者参考。资源包仅含1个docx文件体积约2.45MB内含封面、中英文摘要、目录及章节正文结构规范可用于了解论文写作框架与排版格式。论文围绕Python网络爬虫、Pandas数据清洗、Flask后端框架与前端技术展开重点介绍Echarts图表与WordCloud词云在天气信息呈现中的应用涵盖温度、湿度、风速等数据的采集、整理与可视化流程。文档还讨论天气数据可视化对环境问题与日常决策的现实意义并附有完整章节划分与关键技术说明便于读者梳理实现思路、提炼创新点或作为同类项目的写作模板。目前已有318人学习下载。1. 从一份毕业设计报告拆出的天气可视化平台很多人拿到「基于 Python 的天气数据可视化平台」这类毕业设计题目第一反应是去装个大屏模板套一下结果卡在数据源上——天气数据从哪来、怎么存、怎么保证字段对得上前端图表这三步没打通模板再漂亮也是空壳。这份来自泉州信息工程学院云计算专业的毕业设计报告给出的技术路线其实很实在Python 爬虫取数MySQL 落库Flask 做后端Echarts 加 WordCloud 做前端呈现B/S 架构不装客户端。它的目标不是做商业气象产品而是把「温度、湿度、风速、风向、云量、降雨量、PM2.5、AQI、生活指数」这些多维数据整合到一个网页里让普通访问者随手点开就能看趋势、看建议。适合拿它当课程设计或毕设底稿的人也适合想练一遍「爬虫—清洗—入库—接口—图表」完整链路的开发者。2. 爬虫取数与 MySQL 表结构设计2.1 为什么先定表结构再写爬虫报告里把数据分成了几块7 天天气、空气质量指数、生活指数、天气新闻、景点推荐。新手常犯的错是先写爬虫把数据抓成一堆 CSV等要建接口时才发现字段名对不上、量纲不统一。常见做法是先按业务实体把表定下来让爬虫的产物直接映射到表字段中间只隔一层清洗逻辑。以报告里的表设计为准几张核心表的字段可以直接抄表名关键字段用途qitiantianqiriqi、tianqi、wendu、fengji7 天天气趋势shenghuozhishuzhishu、jianyi、miaoshu生活指数与出行建议tianqixinwenxinwenbiaoti、xinwenneirong、faburiqi天气新闻列表yonghuyonghuzhanghao、mima、yonghuxingming、touxiang用户信息usersusername、password、role后台管理员账号建表时字段统一用 varchar 200 存文本型数值报告里 wendu、fengji 都是 varchar好处是解析容错高代价是后续做数值计算要转类型。如果要做趋势图建议在入库时就额外加一列 int 型的 wendu_num避免在 SQL 里反复 CAST。CREATE TABLE qitiantianqi ( id BIGINT PRIMARY KEY AUTO_INCREMENT, addtime TIMESTAMP DEFAULT CURRENT_TIMESTAMP, riqi VARCHAR(200) COMMENT 日期, tianqi VARCHAR(200) COMMENT 天气, wendu VARCHAR(200) COMMENT 温度, wendu_num INT COMMENT 温度数值用于绘图, fengji VARCHAR(200) COMMENT 风级 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;这段建表语句的关键点有三个ENGINEInnoDB保证事务和外键支持utf8mb4避免中文和表情符号乱码wendu_num是给 Echarts 折线图用的冗余字段。参数上addtime用CURRENT_TIMESTAMP自动填充省掉后端每次手动写时间。2.2 用 requests 加解析库抓取并清洗爬虫部分报告只提到「基于 Python 的网络爬虫技术」没写具体库。这个场景下合格的做法是 requests 发请求、lxml 或 BeautifulSoup 解析pandas 做清洗。下面是一段可直接改选择器复用的骨架import requests, pandas as pd from lxml import etree HEADERS {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)} def fetch_weather(url): # 加超时避免个别站点慢响应把整个脚本挂死 resp requests.get(url, headersHEADERS, timeout10) resp.encoding resp.apparent_encoding # 中文站点常需手动指定编码 html etree.HTML(resp.text) rows [] for li in html.xpath(//ul[classtianqi-list]/li): rows.append({ riqi: li.xpath(./span[1]/text())[0], tianqi: li.xpath(./span[2]/text())[0], wendu: li.xpath(./span[3]/text())[0], fengji: li.xpath(./span[4]/text())[0], }) df pd.DataFrame(rows) # 把 23℃ 这类字符串转成纯数字供图表使用 df[wendu_num] df[wendu].str.extract(r(-?\d)).astype(int) return df.drop_duplicates(subset[riqi]) # 去重防止重复抓取插重复行逻辑上分四步请求、解码、XPath 抽取、pandas 清洗。apparent_encoding是容错点很多国内站点 header 里写的编码和实际不一致不加这行中文会变成乱码。timeout10是必须的爬虫脚本最怕单个请求卡死。drop_duplicates针对的是重跑脚本时的重复插入问题比在数据库层加唯一索引更早拦截。提示抓取前先看目标站点的 robots.txt控制请求频率加 time.sleep(1) 间隔别把生产环境当练手场。2.3 数据落库的两种写法清洗完落到 MySQL用 pymysql 直连或 SQLAlchemy 都行。小项目我一般直接 pymysql依赖少、看得清import pymysql conn pymysql.connect(host127.0.0.1, userroot, password你的密码, databaseweather, charsetutf8mb4) cursor conn.cursor() for _, r in df.iterrows(): cursor.execute( INSERT INTO qitiantianqi(riqi,tianqi,wendu,wendu_num,fengji) VALUES(%s,%s,%s,%s,%s), (r[riqi], r[tianqi], r[wendu], r[wendu_num], r[fengji]) ) conn.commit()charsetutf8mb4必须和建表时一致否则中文写进去是问号。iterrows适合小数据量如果抓几千行以上换成executemany批量插入性能差好几倍。3. Flask 后端接口与 Echarts 前端联调3.1 Flask 路由怎么给图表喂数据报告选了 Flask 而不是 Django理由是可扩展、分层少这个判断对头。天气平台的数据接口逻辑很直白查库、拼 JSON、返回。Echarts 要的数据格式是「类目轴 数值轴」两个数组所以后端返回结构要提前对上别让前端再去拆对象。from flask import Flask, jsonify import pymysql app Flask(__name__) def get_conn(): return pymysql.connect(host127.0.0.1, userroot, password你的密码, databaseweather, charsetutf8mb4, cursorclasspymysql.cursors.DictCursor) app.route(/api/weather/7day) def weather_7day(): conn get_conn() with conn.cursor() as cur: cur.execute(SELECT riqi, wendu_num FROM qitiantianqi ORDER BY riqi LIMIT 7) rows cur.fetchall() conn.close() # 拆成 Echarts 需要的两个数组 return jsonify({ dates: [r[riqi] for r in rows], temps: [r[wendu_num] for r in rows] })DictCursor让查询结果直接是字典省掉手动映射下标。接口只返回图表真正要用的两个数组别把整行数据糊给前端字段越少联调越快。ORDER BY riqi排序很重要数据库默认返回顺序不保证和写入顺序一致不排序折线图会乱跳。3.2 Echarts 折线图和柱状图的对接前端拿到dates和temps后直接塞进 Echarts 的xAxis.data和series.data。下面是最小可跑的配置fetch(/api/weather/7day) .then(res res.json()) .then(data { const chart echarts.init(document.getElementById(tempChart)); chart.setOption({ tooltip: { trigger: axis }, // 鼠标悬停显示数值 xAxis: { type: category, data: data.dates }, yAxis: { type: value, name: 温度(℃) }, series: [{ name: 温度, type: line, smooth: true, // 平滑曲线观感更好 data: data.temps, areaStyle: {} // 面积填充突出趋势 }] }); });几个参数值的留意trigger: axis是折线图该用的提示方式用item会只在点上触发体验差。smooth: true会牺牲一点数据准确感换视觉流畅如果做的是严谨分析图建议关掉。柱状图换type: bar即可空气质量指标AQI、PM2.5用柱状比折线更直观。空气质量模块报告提到要展示 PM2.5 和 AQI这两个量级差很大放同一坐标系会被压扁常见做法是双 Y 轴yAxis: [ { type: value, name: AQI }, { type: value, name: PM2.5, position: right } ], series: [ { name: AQI, type: bar, data: aqiData }, { name: PM2.5, type: line, yAxisIndex: 1, data: pmData } ]yAxisIndex: 1指向第二个 Y 轴这是双轴图的核心参数漏写就会两个系列都挂在左轴。3.3 WordCloud 词云在气象文本上的用法报告的天气新闻模块用到了 WordCloud这块主要面向新闻标题和内容的词频统计。流程是把新闻文本取出来jieba 分词去掉停用词再用 WordCloud 生成图片或交给前端 wordcloud2.js 渲染。import jieba from wordcloud import WordCloud text .join([r[xinwenbiaoti] for r in news_rows]) words .join(jieba.cut(text)) # 过滤单字和常见无意义词 stop set([的, 了, 和, 是, 在]) filtered .join([w for w in words.split() if len(w) 1 and w not in stop]) wc WordCloud(font_pathmsyh.ttc, width800, height400, background_colorwhite).generate(filtered) wc.to_file(static/wordcloud.png)font_path是中文词云最容易踩的坑不指定中文字体生成出来全是方块。len(w) 1过滤掉单字气象文本里单字多是虚词去掉能让高频实词更突出。4. 角色权限、测试与几个真实坑位4.1 管理员与用户双角色的落法报告里功能和用例图都写得很清楚管理员管用户、新闻、空气质量、7 天天气、生活指数、景点推荐用户看首页、个人中心、各类数据。落到代码里最省事的做法是users表里的role字段做区分登录后把角色写进 session路由上加装饰器校验。from functools import wraps from flask import session, redirect, url_for def admin_required(f): wraps(f) def wrapper(*args, **kwargs): if session.get(role) ! 管理员: return redirect(url_for(login)) return f(*args, **kwargs) return wrapper注意session 里存角色比每次查库快但角色变更后要重新登录才生效做权限管理时心里要有数。密码别明文存报告里mima、password都是 varchar 直存实际部署前一定要用 werkzeug 的generate_password_hash做哈希登录时用check_password_hash比对这是毕设答辩时评委最容易追问的点。4.2 功能测试该盯哪几个点报告的测试章节写得比较简略只提了功能测试。真跑起来至少要覆盖三类数据类接口返回字段是否齐全、越权访问是否被拦截、边界数据是否报错。数据接口测试可以直接用 curl 过一遍# 验证 7 天天气接口返回结构与长度 curl -s http://127.0.0.1:5000/api/weather/7day | python -c import sys, json d json.load(sys.stdin) assert len(d[dates]) len(d[temps]), 日期与温度数量不一致 print(接口字段校验通过共, len(d[dates]), 条) 这种自校验脚本比人眼翻页面靠谱字段错位、长度不匹配能立刻暴露。越权测试就是拿普通用户 session 去访问管理员路由看是否被重定向边界测试是往接口塞空数组和超长字符串看后端有没有做异常捕获不捕获就直接 500 暴露堆栈。4.3 上生产前的三个高频坑第一个是爬虫目标站点改版导致 XPath 失效接口不再报错但数据为空。加一层「抓取条数为 0 就告警」的判断比等用户反馈早发现问题。第二个是 MySQL 连接没关Flask 调试模式反复重载会耗尽连接数所有connect都配with或 try/finally 关闭。第三个是时间字段时区addtime用数据库CURRENT_TIMESTAMP时注意容器和宿主机的时区差异否则「今天」的天气可能因为差几个小时显示成昨天。这三处不解决答辩演示那天很可能当着老师的面翻车。本文还有配套的精品资源点击获取
返回列表