基于Python的天气数据爬取与可视化实战:从requests到Tkinter界面

发布时间:2026/9/15 17:18:07

基于Python的天气数据爬取与可视化实战:从requests到Tkinter界面 简介基于Python实现的天气数据爬取与可视化项目面向计算机相关专业在校学生的课程设计、毕业设计及初期立项演示也适合有基础爬虫与可视化学习需求的Python开发者。代码包含详细注释配有界面演示可直观了解从数据抓取、清洗存储到图表展示的完整流程。资源包共20个文件压缩后约393KB核心为3个Python脚本天气数据爬取、两份数据分析与可视化、2个CSV数据文件、1张界面演示截图以及README说明、项目配置和依赖记录等目录结构清晰。已有107人学习下载。项目代码经过测试运行成功答辩评审平均分96分便于直接使用或在原基础上二次开发。通过学习这份资源可以掌握天气类数据的爬取思路、文件读写与可视化方法并借助注释快速理解每段逻辑适合作为课设作业的参考模板或实战练手项目。1. 从课程设计到可运行的天气爬虫可视化程序每年到课程设计季天气数据爬取和可视化就会出现在大量 Python 选题里。你大概率见过这样的同学兴致勃勃调好了爬虫却卡在数据解析上画好了图表却不知道怎么放进界面里演示。其实这个题目真正考的不是“能不能抓到数据”而是你能否把网络请求、HTML 解析、数据清洗、可视化展示四个环节串成一条完整链路并且让代码能被别人看懂。本文就以标题里的“基于 Python 实现简单的天气数据爬取和可视化”为主线写一套可以直接抄、能跑通、注释齐全的完整方案。我会选用 requests BeautifulSoup 抓取公开网页数据用 matplotlib 做可视化再用 Tkinter 做一个最简单的界面演示。这套组合不依赖重型框架环境搭建成本低也足够应付高分课程设计。2. 天气数据爬取的技术选型与反爬边界2.1 数据源选择直接爬网页还是调 API做天气爬取时第一个要拍板的事是数据源。常见做法有两种调天气 API如 OpenWeatherMap、心知天气或者直接爬网页。API 的优点是数据结构化好、字段齐全但通常需要注册 key而且免费额度有限直接爬网页则不需要 key只要目标网站没有强反爬就能用 requests 把页面抓下来再用 BeautifulSoup 解析 HTML。课程设计里我更推荐后者因为你能在报告中写清楚“如何分析请求头”“如何定位 DOM 节点”这些过程才是评分老师愿意看到的内容。我一般会选那种结构稳定的公开天气页面比如中国天气网的某个城市页面或者 wttr.in 这类极简风格的天气服务它们的 HTML 结构相对固定适合做教学案例。2.2 requests BeautifulSoup 的解析模型与反爬识别拿到一个网页以后爬虫的核心就两件事发请求、解析响应。requests 负责把 HTTP 请求发出去BeautifulSoup 负责把返回的 HTML 字符串变成一棵可遍历的树。这两者组合的解析模型是先soup.find()定位目标节点再用.text取出文本用.get(属性)取出标签属性。实际爬取时很多页面会校验请求头里的 User-Agent甚至校验 Referer、Cookie。如果直接发裸请求大概率只能拿到一个 403 或者一个登录跳转页面。所以我一般会在请求头里带上浏览器信息必要时再加一个间隔等待。下面是一张常用的请求头参数表也是你调参时重点看的几个字段。参数名典型值作用User-AgentMozilla/5.0 ...标识客户端类型绕过最简单的 UA 校验Refererhttps://target.com/告诉服务器请求来源部分站点会校验Cookiesessionxxx; ...维持会话状态有些数据需要登录后可见Accept-Languagezh-CN,zh;q0.9让服务器返回中文内容避免乱码2.3 频率控制与合规边界爬虫不是请求发得越快越好。对目标站点做高频请求一是容易触发 IP 封禁二是给对方服务器造成压力这个在课程设计里也是忌讳。我一般会在两次请求之间加time.sleep(1)如果数据量小甚至加到 2 秒。另外在代码注释里写清楚数据来源和抓取时间这既是工程习惯也是合规意识的体现。你要在报告中说明仅抓取公开静态页面不碰登录接口不遍历敏感路径不做商业用途。这套方案在课堂上使用没有任何问题但如果你要放到生产环境必须先去查看目标网站的robots.txt确认是否允许爬取。3. 实现天气数据爬虫带详细注释的核心代码3.1 定义数据模型与抓取函数动手写爬虫前先想清楚你要拿哪些字段。一个简单的天气数据模型至少要有日期、最高温、最低温、天气状况、风力这几项。把它们定义成字典后续可视化时直接按 key 取值比用元组或散装变量清晰得多。下面这段代码我写了详细注释你直接复制到项目里就能跑通。import requests from bs4 import BeautifulSoup import time # 数据模型用一个字典保存单日天气信息 def empty_weather(): return { date: , high: 0, low: 0, condition: , wind: } # 核心抓取函数传入目标URL返回解析后的天气列表 def fetch_weather(url, headersNone): if headers is None: headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) } resp requests.get(url, headersheaders, timeout10) resp.encoding utf-8 # 大部分中文天气站用utf-8个别用gbk soup BeautifulSoup(resp.text, html.parser) return soup这段代码里requests.get的timeout参数很关键它控制了最长的等待时间避免某个请求卡死整个程序。resp.encoding如果设错了解析出来的中文会变成乱码常见做法是先打印resp.apparent_encoding看一眼再决定。BeautifulSoup的第二个参数指定了解析器html.parser是 Python 标准库自带的不需要额外安装比lxml更省事。3.2 解析 HTML 提取关键字段数据抓下来以后真正的难点是定位 HTML 里的节点。你需要在浏览器里按 F12 找到目标数据的父节点然后写选择器。我用过的最常见的结构是每天的气象信息放在一个ul classt clearfix下每个li对应一天的数据。定位方式有两种.find()只取第一个.find_all()取所有。下面示例演示如何提取 7 天的天气列表并处理空值和单位。def parse_weather(soup): weather_list [] # 定位到包含每日数据的列表容器class名称以实际页面为准 days soup.find_all(li, class_sky skyid) if not days: days soup.select(.t li) # 备选选择器 for day in days[:7]: # 只取前7天控制数据量 item empty_weather() # 日期在h1标签内形如7日今天 date_tag day.find(h1) if date_tag: item[date] date_tag.text.strip() # 高温和低温分开放在两个span里 high_tag day.find(span, class_tem) if high_tag: # 把字符串里的℃去掉转成整数 item[high] int(high_tag.text.replace(℃, ).strip()) low_tag day.find(p, class_tem) if low_tag: item[low] int(low_tag.span.text.replace(℃, ).strip()) # 天气状况在p标签的title属性里 cond_tag day.find(p, class_wea) if cond_tag: item[condition] cond_tag.text.strip() weather_list.append(item) return weather_list这里有两个常见的坑一是class里有多个类名时直接用class_sky skyid这样写匹配的是完整字符串不是子串如果你不确定就改用.select(.sky)二是find_all返回的列表可能包含你不需要的元素比如页脚的重复天气信息所以我才加了[:7]切片只取前 7 天。解析完成后建议立刻打印一条记录看结构对不对再进入下一步。3.3 异常兜底与注释规范写爬虫最容易忽略的是异常处理。网络请求可能超时、返回空页面、甚至目标节点被删改这些都要兜住。我给你一个最小但完整的异常处理模板能覆盖 80% 的失败场景。同时课程设计对注释要求很高我的注释原则是说明“为什么这么做”而不是“这句代码在做什么”这样才能体现你对逻辑的理解。def safe_fetch(url, retries3): for i in range(retries): try: soup fetch_weather(url) return parse_weather(soup) except requests.exceptions.Timeout: # 超时重试等待时间逐次增加 wait (i 1) * 2 print(f[警告] 请求超时{wait}秒后重试) time.sleep(wait) except Exception as e: # 兜底捕获所有异常避免程序崩溃 print(f[错误] 抓取失败{e}) return [] return [] # 重试耗尽返回空列表这段代码的返回值设计很重要失败时返回空列表而不是抛出异常。这样主程序可以继续执行可视化部分至少能显示一个空图或提示信息而不是黑屏退出。retries参数控制重试次数我一般设 3 次再多就是对目标网站不礼貌了。把fetch_weather和parse_weather分开写是为了让每层逻辑独立方便你在报告里分别解释网络层和解析层的设计。4. 可视化与界面演示从数据到图表再到窗口4.1 matplotlib 绘制温度曲线与天气分布拿到 7 天数据后可视化就顺理成章了。最常用的图是温度曲线横轴日期两根折线分别表示最高温和最低温。为了更直观我会把天气状况作为图上的文本标注。matplotlib 的画图逻辑是先准备数据列表再plt.plot()最后plt.show()。下面这段代码可以直接嵌入你的主程序。import matplotlib.pyplot as plt def plot_temperature(weather_list): if not weather_list: print(没有数据无法绘图) return dates [w[date] for w in weather_list] highs [w[high] for w in weather_list] lows [w[low] for w in weather_list] plt.figure(figsize(10, 5)) plt.plot(dates, highs, markero, label最高温) plt.plot(dates, lows, markers, label最低温) # 在最高温折线上方标注天气状况 for i, cond in enumerate([w[condition] for w in weather_list]): plt.text(i, highs[i] 1, cond, hacenter, fontsize9) plt.title(近7天天气趋势) plt.xlabel(日期) plt.ylabel(温度(℃)) plt.legend() plt.grid(True) plt.tight_layout() plt.show()这里marker参数给折线加了数据点标记o是圆形s是方形可视化课设里常用。plt.text的坐标是(x, y)我让y取最高温加 1这样文字不会盖住折线。tight_layout()解决标签被截断的问题这个细节经常被忽略。如果你用的是中文标签一定要在代码开头设置plt.rcParams[font.sans-serif] [SimHei]否则中文会变成方块。4.2 Tkinter 嵌入图表实现界面演示界面演示部分很多同学会考虑 web 框架其实课程设计里我用 Tkinter 就够了。它是 Python 自带的 GUI 库不需要额外安装启动快演示时也不依赖浏览器环境。思路是窗口里放一个按钮和一个画布点击按钮后抓取最新数据并绘图然后把图表保存成图片再显示到窗口里。matplotlib 直接嵌入 Tkinter 需要FigureCanvasTkAgg最简单的是用如下方式。import tkinter as tk from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg def show_interface(): root tk.Tk() root.title(天气爬取与可视化演示) # 用于绘制图表的容器 fig plt.Figure(figsize(6, 4)) ax fig.add_subplot(111) canvas FigureCanvasTkAgg(fig, masterroot) canvas.get_tk_widget().pack() def refresh(): # 点击刷新按钮时重新抓取和绘制 data safe_fetch(https://example.com/weather) ax.clear() ax.plot([d[high] for d in data], labelhigh) ax.plot([d[low] for d in data], labellow) ax.legend() canvas.draw() btn tk.Button(root, text刷新数据, commandrefresh) btn.pack() refresh() # 启动时先展示一次 root.mainloop()这段代码演示了按钮绑定事件和 canvas 刷新的核心逻辑。FigureCanvasTkAgg把 matplotlib 的 figure 对象嵌入到 Tk 窗口里每次刷新时调用ax.clear()清空旧图再画新图canvas.draw()更新显示。如果你不想用 Tkinter也可以改用pywebview或Flask做可视化界面但我个人认为 Tkinter 在课设答辩时更稳因为它不需要额外端口和服务配置双击就能运行。4.3 数据持久化与刷新逻辑界面演示不只是看一个静态图表你要让观看者知道数据是“实时抓取”的。所以刷新逻辑非常重要。我一般会加两个功能一是把抓到的数据存成 CSV 文件方便事后核对二是每次刷新前清空旧数据并用状态栏提示“更新完成”。这既能体现你对数据生命周期的理解也能避免答辩时因为缓存问题被追问。写入 CSV 的代码很简单。import csv def save_weather(weather_list, filenameweather.csv): with open(filename, w, newline, encodingutf-8) as f: writer csv.DictWriter(f, fieldnames[date, high, low, condition, wind]) writer.writeheader() writer.writerows(weather_list) print(f数据已保存到 {filename})newline是为了避免 Windows 下 CSV 文件多出空行这个坑很常见。encodingutf-8保留中文不乱码。在界面刷新时先调用safe_fetch再调用save_weather最后更新图表这样你的程序就形成了“抓取-保存-可视化”闭环。5. 进阶技巧验证数据正确性与提高爬虫稳定性5.1 用日志和重试机制替换简单 print你在课设答辩时评委可能会问“你的程序怎么应对目标网站改版”直接的回答是我用了日志和重试。简单的print在代码跑完后什么痕迹都留不下而logging模块能记录到文件方便排查。我一般会做如下替换。import logging logging.basicConfig( filenameweather.log, levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s ) logging.info(开始抓取天气数据)更进一步的稳定性优化是设置请求频率限制把time.sleep(1)改成从配置里读取的间隔值这样你在演示时可以把间隔调小在生产时调大。此外还可以用requests.Session()复用连接减少 TCP 握手次数这个优化在抓取多个页面时效率提升明显。Session 对象会自动保存 cookie某些需要先访问首页获得会话的站点也能正常处理。5.2 3 个验证数据正确性的方法可视化结果是不是可信要看数据源头对不对。我常用三个方法验证爬虫抓到的数据第一打印原始 HTML 片段确认选择的节点没有变化第二把抓到的日期和本地系统日期做对比防止抓到旧数据第三用两个不同网站的数据做交叉对比比如同时抓取同一个城市在两个站点的温度差值在 2 度以内基本可以认为没问题。# 验证HTML节点是否匹配在命令行里直接测试选择器 python -c from bs4 import BeautifulSoup; print(BeautifulSoup(open(page.html, encodingutf-8), html.parser).select_one(.tem).text)如果这条命令能输出温度值说明选择器写的没错。如果输出None说明页面结构变了你需要重新查看 DOM 节点。交叉对比时注意两个站点的更新时间可能不同最好选择同一小时的整点数据避免因为时间差导致误差过大。5.3 从课程设计到工程化的差距课程设计做完后如果你想把它变成能长期跑的小工具还需要补三块配置管理、单元测试、模块解耦。比如把 URL、User-Agent、刷新间隔等抽到一个config.py里而不是写在主程序里为parse_weather写一个简单的测试用例用一段固定的 HTML 字符串验证解析逻辑是否正确。这些做法在课设里是加分项在真实项目里是必备项。最后提醒你一点爬虫代码的注释风格要统一我习惯用中文注释但变量名和函数名用英文这样报告和代码都能兼顾可读性。如果你希望进一步优化界面演示的观感可以在show_interface里加一个下拉框切换城市或者用matplotlib的动画功能让曲线逐段出现这些都能让演示效果更接近正式的成品。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/9/15 17:18:07

基于Spring Boot的旅游管理系统设计与实现:从四层架构到部署交付

简介:这是一套基于Spring Boot框架的旅游管理系统毕业设计资源,适合计算机相关专业学生、Java Web开发者作为课程设计或毕业设计参考。系统采用Java与MySQL构建,包含管理员、用户双角色,覆盖景点购票、酒店预定、游记分享等核心业…

2026/9/15 17:28:08

Python实现海洋SSTA的EOF分析全流程:从数据下载到物理解读

1. 为什么用EOF分析SSTA不是“炫技”,而是解决真问题的必要手段你有没有遇到过这样的情况:手头有一堆全球海表温度异常(SSTA)的NetCDF文件,时间跨度几十年,空间分辨率是11,变量维度是(time, lat…

2026/9/15 17:28:08

VisionMaster本地图像模块:离线调试机器视觉方案的实用指南

做机器视觉方案调试,最烦的事情是什么?我个人觉得,不是算法效果差,而是每次改完参数都要跑一遍产线,等相机重新拍图。尤其是项目前期,相机还没装好、或者现场图片没批量传出来的时候,整个调试进…

2026/9/15 17:28:08

CSR-DCF目标跟踪算法源码运行全指南:从原理到调参避坑

进入计算机视觉这个圈子,尤其是视频目标跟踪方向的人,基本都绕不开CSR-DCF这个名字。它是2017年CVPR上的工作,全称是Discriminative Correlation Filter with Channel and Spatial Reliability,也就是带通道可靠性和空间可靠性的判…

2026/9/15 17:23:07

SQL Server AlwaysOn可用性组从零部署:高可用架构实战指南

我有个习惯,技术圈里只要刮起“部署”风,我总会先往数据库这层瞟一眼。这不,最近大家聊本地部署聊得火热,从大模型到Docker再到CI/CD自动部署,人人都能把几十个容器跑起来,但真正轮到底层数据库的高可用部署…

2026/9/15 4:54:30

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/15 0:01:16

AI英语单词APP开发:自适应学习算法与移动端优化实践

1. 项目概述 作为一名在移动应用开发领域摸爬滚打多年的老手,我最近完成了一个AI英语单词APP的开发项目。这个项目将传统单词记忆方法与现代AI技术相结合,打造了一款能够智能适应不同用户学习习惯的英语学习工具。 市面上大多数单词APP都存在一个通病&a…

2026/9/15 0:01:16

Flutter与OpenHarmony结合开发手语学习APP实战

1. 项目背景与核心价值作为一名同时接触过Flutter和OpenHarmony的开发者,最近我完成了一个基于Flutter for OpenHarmony的手语学习APP实战项目。这个项目最大的特点在于实现了跨平台框架与国产操作系统深度结合的创新实践——用Flutter开发的应用能完美运行在OpenHa…

2026/9/15 0:01:16

六个月成为机器人工程师:从ROS2到SLAM的实战路径

1. 六个月的紧迫感从哪来:先搞清楚你要成为哪种机器人工程师说实话,六个月的期限并不是一个宽松的时间线。市面上任何一本正经的机器人学教材都超过五百页,ROS2的官方文档可以翻到你怀疑人生,再加上ABB、KUKA这些工业机器人厂家动…

2026/9/15 14:22:53

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/14 13:53:59

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/15 11:42:23

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码