☰
Python爬虫实战:天气数据采集与可视化入门教程
2026/9/28 8:16:49 网站建设 项目流程

Python实战项目千千万,但要说既练爬虫、学数据处理、又能产出漂亮图表的入门项目,天气数据爬取+数据可视化绝对是我最推荐的那一个。跑通以后拿到的不是一堆看不懂的控制台输出,而是清清楚楚的折线图、柱状图,甚至可以生成一个交互式HTML图表,发给谁都能直接打开看。这个项目适合什么基础的人?说实话,只要会一点Python语法、装过第三方库,哪怕完全没写过爬虫,跟着做下来完全没问题。

简单说,这个项目做三件事:程序自动向天气数据接口发起请求,拿到指定城市的实时气温、湿度、风向、天气预报;把数据清洗成规矩的结构存到CSV;最后用matplotlib画出静态图表、用pyecharts生成交互式网页图表。我写这类入门项目有个原则:代码不要太长,但必须每一步都能解释清楚“为什么这么写”。下面的内容全部来自我实际调试过的方案,包括城市ID怎么找、字段怎么清洗、中文乱码怎么处理、接口返回异常怎么办,都是一步步踩过坑后沉淀下来的。

1. 项目整体设计与技术选型思路

1.1 为什么天气数据适合做爬虫实战

很多初学者挑实战项目时容易走两个极端。一个极端是去爬那种需要复杂登录、滑块验证、加密参数的网站,结果一周时间全耗在反爬对抗上,最后连数据都拿不回来;另一个极端是只读书上的教程,跟着敲完一段代码却完全不知道怎么迁移到别的地方。

天气数据恰好卡在中间:它足够真实,数据来自线上接口,包含了真实的HTTP请求、JSON解析、异常处理这些核心环节;它又足够简单,不需要登录、不需要验证码、不需要处理动态渲染的复杂页面。更关键的是,爬完之后的展示效果好——温度柱状图、温湿度散点图、温度变化折线图,每一种都能让人直观感受到爬虫到底“爬”到了什么。把天气数据练熟,之后再去爬电商商品、爬新闻资讯、爬各类公开数据接口,思路是完全可以复用的。

用个生活化的类比:爬虫就像你雇了一个跑腿小哥,你给他一个地址(URL)、告诉他带什么工具(请求头headers)、然后他从目的地取回一个快递(响应数据),你负责拆开快递箱(JSON或HTML)把有用的东西挑出来。搞清楚这条链路,爬虫的骨架就立住了。

1.2 技术栈选型:为什么不用Scrapy框架

这个项目我选了requests、csv、matplotlib、pyecharts这几个核心库,刻意没有上Scrapy框架。很多人一上来就追求“工业级方案”,结果被框架的并发模型、中间件、Pipeline绕得头晕。对一个小体量学习项目来说,requests足够轻,一行一个请求,出问题能立刻定位;Scrapy适合大规模采集、需要调度器和并发管理的场景,等你理解单线程请求怎么处理、反爬怎么应对之后,再上手Scrapy会顺畅很多。

各模块职责如下表:

技术组件职责选型理由
requests发送HTTP请求,获取接口数据语法简洁,正确处理Cookie、headers、超时设置
json解析接口返回的JSON结构Python原生支持,快速提取嵌套字段
csv存储清洗后的天气数据通用性强,Excel直接打开,新人友好
matplotlib绘制静态图表(柱状图、散点图、折线图)生态成熟,中文资料多,定制自由度大
pyecharts生成交互式HTML图表图表酷炫,支持鼠标悬浮、缩放,适合展示

整个项目的数据流是:请求接口 -> 拿到JSON -> 解析字段 -> 清洗单位与类型 -> 写入CSV -> 读取CSV -> 画图。这样拆开之后,爬虫和可视化两个模块可以独立调试,后面想换数据源或者换图表类型都不会牵扯到对方。

2. 数据采集模块:从零开始爬天气数据

2.1 先搞清数据从哪来:开发者工具实战

很多教程一上来直接甩给你一个URL,然后说“爬这个”,但URL背后怎么来的没人讲。实战里找数据源的方法,比爬虫代码本身更重要。

拿天气数据举例,你可以直接在浏览器打开中国天气网的某个城市页面,按F12进入开发者工具,切到“网络”(Network)面板,勾选“XHR”或“Fetch/XHR”类型的请求,然后刷新页面。这时你会看到页面发起的各类请求,很多数据其实是页面JavaScript脚本在加载完成后向后台接口发请求获取的。找到返回内容是JSON、且体积不大的请求,右键复制URL,用浏览器新标签页打开,就能看到接口返回的原始数据结构。

我在实际调试中发现,天气网站有几个公开接口是非常稳定的。它们没有加密参数、不带签名、返回的就是标准JSON,非常适合学习。比如以下两个接口:

实时天气:http://www.weather.com.cn/data/sk/{城市ID}.html 当天预报:http://www.weather.com.cn/data/cityinfo/{城市ID}.html

其中“城市ID”是城市编码,比如北京是101010100、上海是101020100。怎么找到这个ID?在浏览器打开对应城市的天气页面,URL里那串数字就是城市ID。例如 www.weather.com.cn/weather/101010100.shtml 这个地址里的 101010100就是北京的城市编号。注意接口字段在不同时间可能会有调整,这不是问题——只要你会用开发者工具看真实返回,字段变了改个名字就能继续跑。

2.2 第一个爬虫:请求实时天气接口

先用最简代码把这个接口跑通。新建一个Python文件,比如 weather_spider.py,写入下面这段:

import requests city_id = "101010100" # 北京 url = f"http://www.weather.com.cn/data/sk/{city_id}.html" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" } resp = requests.get(url, headers=headers, timeout=5) data = resp.json().get("weatherinfo", {}) print(data)

运行后你能看到类似这样的输出:

{ "city": "北京", "cityid": "101010100", "temp": "24.1", "WD": "南风", "WS": "2级", "SD": "23%", "time": "11:00" }

里面有实时温度temp、风向WD、风力WS、相对湿度SD。注意这里所有字段都是字符串,这是原始数据的常态,后面需要自己清洗。那两行headers里的User-Agent是干什么用的?简单说,服务器会通过这个字段识别客户端类型。很多网站会把默认的python-requests识别为非浏览器请求而直接拒绝,加上一个常见浏览器的User-Agent就能规避大部分初级拦截。

2.3 批量爬取多城市:循环里最不能省的间隔

单城市能爬到,多城市就是加一个for循环的事。我准备一个城市ID字典,覆盖北京、上海、广州、深圳、杭州、成都、武汉、南京八个城市,这样后面画对比柱状图时数据更丰富,视觉效果也会好很多。

CITY_IDS = { "北京": "101010100", "上海": "101020100", "广州": "101280101", "深圳": "101280601", "杭州": "101210101", "成都": "101270101", "武汉": "101200101", "南京": "101190101", }

批量请求时,我建议在每个请求之间主动加 time.sleep(2) 的间隔。这既是礼貌,也是保护自己的手段。爬虫说到底就是向服务器发起大量请求,如果你一秒内连刷上百次,服务端日志里全是你,轻则当前IP被临时限制,重则触发风控规则影响后续访问。控制频率是爬虫的基本礼仪,也是实战中必须养成的习惯。

2.4 反爬意识与合规边界

我在这里必须说清楚:这个项目的数据来源于公开的天气接口,接口本身允许匿名访问,我把它作为教学案例的前提是“合理频次、个人学习、不涉及商业分发”。做爬虫一定要守住合规底线:不爬需要登录才能看的内容、不绕过付费墙、不暴力请求导致对方服务异常、不对爬到的数据做商业化操作。

实战中如果遇到接口突然拿不到数据,先别怀疑自己代码,大概率是触发频率限制或者接口改版了。触发限制后先停一段时间再试,不要立刻换IP硬刚。改版了就用开发者工具重新找接口,这个方法我在后面第6章还会详细讲。

3. 数据清洗与CSV存储:拿到原始数据后别急着画图

3.1 原始数据长什么样:洗净才能用

爬虫拿到的JSON字段看起来清晰,但离“能直接画图”还有几步。我实际运行后取到的一个完整字段集是这样的:

{ "city": "北京", "temp": "24.1", "temp_high": "32℃", "temp_low": "24℃", "humidity": "23%", "wind_dir": "南风", "wind_level": "2级", "weather": "多云转晴" }

仔细看会发现问题不少。第一,温度是字符串“24.1”,画图时需要转成float。第二,预报里最高温和最低温带着“℃”单位,不处理的话,像 int("32℃") 这种代码直接报错。第三,湿度“23%”带百分号,要转成23这样的整数才能计算。写一个专门的清洗函数是必要的,别在主体逻辑里穿插replace和strip,代码会乱成一锅粥。

def clean_value(value, convert_type=float): """去掉常见单位并转换类型,转换失败返回0""" try: cleaned = str(value).replace("℃", "").replace("%", "").strip() return convert_type(cleaned) except (ValueError, TypeError): return 0

这个函数能同时处理温度和湿度。单独拆出来还有一个好处:如果换了数据源,字段单位变了,只需要改这一处,不用动整个逻辑。

3.2 用csv模块保存数据:Excel直接能打开

清洗完的数据我建议立刻落盘保存。原因很实际:爬虫和可视化往往是分开调试的,你不可能每调一次图标就重新爬一次数据,把中间结果存下来能节省大量时间。CSV是我在这个阶段的首选格式,Excel直接能打开,肉眼检查数据是否合理非常方便。

写入时有个容易被忽略的细节:文件编码要指定为 utf-8-sig,而不是默认的 utf-8。原因在于Excel打开utf-8编码的CSV时会出现中文乱码,而utf-8-sig带上了BOM头,Excel能正确识别中文。如果你用的是macOS的Numbers,两者区别不大,但在Windows上,这个细节能避免一个看似“灵异”的乱码问题。

import csv def save_to_csv(rows, filename="weather_data.csv"): fieldnames = ["city", "time", "temp", "temp_high", "temp_low", "humidity", "wind_dir", "wind_level", "weather"] with open(filename, "w", newline="", encoding="utf-8-sig") as f: writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() writer.writerows(rows)

3.3 为什么建议存CSV而不是直接上数据库

不少入门者一听到存储就想着MySQL、SQLite,仿佛不用数据库就不专业。这个项目的数据量一天也就几百条,MySQL完全是大炮打蚊子。CSV的好处是零配置、零依赖、人类可读,学完CSV以后真需要上数据库时,你会发现无非是把 csv.DictWriter 换成 INSERT 语句,核心的数据结构是一样的。

当然,如果后续想做定时采集一个月的数据、再做历史趋势查询,那迁移到SQLite成本也不高。SQLite就一个文件,不用安装服务,Python自带sqlite3模块,属于下一步扩展最平滑的选择。

4. 数据可视化:让数字变成一眼能懂的图表

4.1 中文乱码问题:必须先解决再画图

matplotlib画中文第一步不是调数据,而是设置中文字体。直接跑默认配置画图,图上的“北京”“温度”全变成一个个方框,这是matplotlib的默认字体里没有中文字符导致的。解决办法是在画图前加两行配置:

plt.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei", "PingFang SC"] plt.rcParams["axes.unicode_minus"] = False # 解决负号显示成方框的问题

SimHei是黑体,Windows系统基本都自带;Microsoft YaHei是微软雅黑;PingFang SC是macOS的字体。把它们罗列在一起,程序会自动在系统里找一个可用的。第二行axes.unicode_minus设置为False很重要,否则坐标轴上的负数会变成乱码一样的方框。

如果你在Linux服务器上运行,没有Windows或macOS的中文字体,那就需要先把中文字体安装到系统里,比如通过fontconfig安装文泉驿微米黑,然后把字体名填进sans-serif列表。这个步骤一度是我在服务器上跑脚本时踩过最大的坑。

4.2 多城市温度柱状图:最直观的效果图

清洗和存储都搞定后,读取CSV画图。用matplotlib画一个多城市实时温度对比柱状图,这应该是整个项目里最快出效果的部分:

import csv import matplotlib.pyplot as plt plt.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei", "PingFang SC"] plt.rcParams["axes.unicode_minus"] = False with open("weather_data.csv", "r", encoding="utf-8-sig") as f: rows = list(csv.DictReader(f)) cities = [row["city"] for row in rows] temps = [float(row["temp"]) for row in rows] plt.figure(figsize=(10, 5)) bars = plt.bar(cities, temps, color="skyblue", width=0.5) plt.title("多城市实时温度对比", fontsize=16) plt.ylabel("温度(℃)") plt.ylim(0, max(temps) + 5) for bar, temp in zip(bars, temps): plt.text(bar.get_x() + bar.get_width() / 2, bar.get_height() + 0.5, f"{temp}℃", ha="center", fontsize=12) plt.tight_layout() plt.savefig("temperature_bar.png", dpi=200) plt.show()

运行后你会得到一个柱状图文件,每根柱子顶部标了具体温度,城市名正常显示中文。保存文件时用 dpi=200 是为了保证图片导出来够清晰,放进课程报告或博客里都不糊。

4.3 进阶玩法:用pyecharts生成可交互图表

matplotlib的图是静态图片,适合打印和嵌入文档。但如果想给别人展示、或者想做出那种鼠标悬浮就显示数值的酷炫效果,我强烈建议加一个pyecharts版本。pyecharts生成的图表是一个HTML文件,双击就能在浏览器里打开,完整保留交互能力。

from pyecharts.charts import Bar from pyecharts import options as opts cities = ["北京", "上海", "广州"] temps = [24.1, 26.5, 29.0] bar = ( Bar() .add_xaxis(cities) .add_yaxis("实时温度(℃)", temps) .set_global_opts( title_opts=opts.TitleOpts(title="多城市实时温度对比"), yaxis_opts=opts.AxisOpts(name="温度(℃)"), ) ) bar.render("temperature_interactive.html")

pyecharts的语法风格和matplotlib差异很大,它采用链式调用,每行一个配置项。初看可能不习惯,但它的官方文档和示例非常齐全,学会一个图之后其余图都是换汤不换药。这里我把折线图、饼图、地图都留给读者自己去扩展——数据和图表逻辑已经搭好,换图类型其实就是换一下组件名。

4.4 让折线图派上用场:连续采集看温度走势

细心的你可能会问:柱状图和散点图用一次采集的数据就够了,折线图怎么画?折线图适合展示时间序列,比如记录同一个城市每隔10分钟的温度,累积成一条曲线,能看出昼夜温度变化趋势。

做法很简单:写一个循环采集函数,调用前面写的 get_weather(),把每次得到的温度追加到列表,然后用 plt.plot() 画折线。我试过跑两小时,拿到的曲线能明显看出午后升温、傍晚回落的规律。这一步完全复用前面的采集函数,只不过从“批量采集多个城市”变成“单城市多次采集”。在代码结构上,因为采集逻辑已经拆成了独立的函数,多城市和多时段两种模式只需要调整调用方式,不需要重写爬虫,这就是模块化的好处。

5. 完整代码整合与运行指南

5.1 项目文件结构

建议把代码拆成两个文件,互不干扰。这是我的目录结构:

weather_project/ ├── weather_spider.py # 采集 + 清洗 + 存储 ├── weather_charts.py # 读取CSV + 绘图 ├── weather_data.csv # 运行后生成的数据文件 ├── temperature_bar.png # 运行后生成的静态图表 └── temperature_interactive.html # 运行后生成的交互式图表

拆分文件的一个额外好处是:以后爬另一个站点时,weather_charts.py基本不用改,只需要让新爬虫输出同样结构的CSV。

5.2 采集与存储完整代码

下面是采集部分完整代码,整合了第2章、第3章的内容,加了异常处理和打印日志,复制就能用。

# -*- coding: utf-8 -*- """ 天气数据采集 + 清洗 + CSV存储完整示例 数据来源:中国天气网公开接口 仅供个人学习使用,请控制请求频率 """ import csv import time from datetime import datetime import requests CITY_IDS = { "北京": "101010100", "上海": "101020100", "广州": "101280101", "深圳": "101280601", "杭州": "101210101", "成都": "101270101", "武汉": "101200101", "南京": "101190101", } HEADERS = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Referer": "http://www.weather.com.cn/", } def clean_number(value, convert_type=float): """去掉℃、%等单位,并转换类型""" try: return convert_type(str(value).replace("℃", "").replace("%", "").strip()) except (ValueError, TypeError): return 0 def get_weather(city_name, city_id): """获取单个城市的实时天气和当天预报""" sk_url = f"http://www.weather.com.cn/data/sk/{city_id}.html" info_url = f"http://www.weather.com.cn/data/cityinfo/{city_id}.html" result = { "city": city_name, "time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), } try: sk_resp = requests.get(sk_url, headers=HEADERS, timeout=5) sk_data = sk_resp.json().get("weatherinfo", {}) result["temp"] = clean_number(sk_data.get("temp", 0)) result["humidity"] = clean_number(sk_data.get("SD", "0%"), int) result["wind_dir"] = sk_data.get("WD", "") result["wind_level"] = sk_data.get("WS", "") info_resp = requests.get(info_url, headers=HEADERS, timeout=5) info_data = info_resp.json().get("weatherinfo", {}) result["temp_high"] = clean_number(info_data.get("temp1", "0℃"), int) result["temp_low"] = clean_number(info_data.get("temp2", "0℃"), int) result["weather"] = info_data.get("weather", "") except Exception as exc: print(f"[警告] 采集 {city_name} 失败: {exc}") return None return result def collect_batch(city_dict, interval=2): """批量采集多城市天气数据""" rows = [] for city, city_id in city_dict.items(): data = get_weather(city, city_id) if data: rows.append(data) print(f"已采集 {city}: 实时{data['temp']}℃, " f"最高{data['temp_high']}℃, 天气{data['weather']}") time.sleep(interval) return rows def save_to_csv(rows, filename="weather_data.csv"): """保存到CSV,utf-8-sig编码防止Excel中文乱码""" if not rows: print("没有数据可保存") return fieldnames = ["city", "time", "temp", "temp_high", "temp_low", "humidity", "wind_dir", "wind_level", "weather"] with open(filename, "w", newline="", encoding="utf-8-sig") as f: writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() writer.writerows(rows) print(f"数据已保存到 {filename}") if __name__ == "__main__": all_data = collect_batch(CITY_IDS) save_to_csv(all_data)

5.3 可视化完整代码

再新建 weather_charts.py,用来读取weather_data.csv并画图。

# -*- coding: utf-8 -*- """ 读取天气CSV并绘制图表 包含matplotlib静态图 + pyecharts交互图 """ import csv import matplotlib.pyplot as plt from pyecharts import options as opts from pyecharts.charts import Bar def load_csv(filename="weather_data.csv"): """读取CSV数据""" with open(filename, "r", encoding="utf-8-sig") as f: return list(csv.DictReader(f)) def setup_chinese_font(): """设置matplotlib中文字体,解决乱码""" plt.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei", "PingFang SC"] plt.rcParams["axes.unicode_minus"] = False def draw_bar_temp(rows): """多城市实时温度柱状图""" setup_chinese_font() cities = [row["city"] for row in rows] temps = [float(row["temp"]) for row in rows] plt.figure(figsize=(10, 5)) bars = plt.bar(cities, temps, color="skyblue", width=0.5) plt.title("多城市实时温度对比", fontsize=16) plt.ylabel("温度(℃)") plt.ylim(0, max(temps) + 5) for bar, temp in zip(bars, temps): plt.text(bar.get_x() + bar.get_width() / 2, bar.get_height() + 0.5, f"{temp}℃", ha="center", fontsize=12) plt.tight_layout() plt.savefig("temperature_bar.png", dpi=200) plt.show() def draw_scatter(rows): """气温与相对湿度散点图""" setup_chinese_font() temps = [float(row["temp"]) for row in rows] humis = [float(row["humidity"]) for row in rows] cities = [row["city"] for row in rows] plt.figure(figsize=(10, 5)) plt.scatter(temps, humis, s=80, color="coral", alpha=0.7) for i, city in enumerate(cities): plt.annotate(city, (temps[i], humis[i]), textcoords="offset points", xytext=(5, 5), fontsize=11) plt.xlabel("气温(℃)") plt.ylabel("相对湿度(%)") plt.title("气温与相对湿度关系散点图", fontsize=16) plt.grid(alpha=0.3) plt.tight_layout() plt.savefig("temp_humidity_scatter.png", dpi=200) plt.show() def draw_interactive_bar(rows): """pyecharts交互式柱状图,生成HTML""" cities = [row["city"] for row in rows] temps = [float(row["temp"]) for row in rows] bar = ( Bar() .add_xaxis(cities) .add_yaxis("实时温度(℃)", temps) .set_global_opts( title_opts=opts.TitleOpts(title="多城市实时温度对比"), yaxis_opts=opts.AxisOpts(name="温度(℃)"), ) ) bar.render("temperature_interactive.html") print("交互式图表已生成: temperature_interactive.html") if __name__ == "__main__": data_rows = load_csv() if data_rows: draw_bar_temp(data_rows) draw_scatter(data_rows) draw_interactive_bar(data_rows) else: print("CSV中没有数据,请先运行 weather_spider.py")

5.4 三步跑通整个项目

安装依赖这一步只装三个库就够了,其他都是Python标准库:

pip install requests matplotlib pyecharts

然后按顺序运行:

python weather_spider.py python weather_charts.py

第一步会在控制台打印每个城市的采集结果,同时生成weather_data.csv。第二步会弹出两个matplotlib窗口(或保存PNG图片),并生成temperature_interactive.html。整个流程跑下来,从请求接口到生成可视化图表,完整闭环就打通了。

如果电脑同时装了Python 2和Python 3,或者走的是conda环境,命令可能是 python3 或 conda activate 之后再执行。确保 pip install 装到的环境和你运行脚本的环境一致,这个基础问题反而是新手最常见翻车点。

6. 常见问题与排查技巧实录

6.1 高频报错速查表

这个项目在实际运行中最容易遇到的报错,我整理成了一张表,每一个都是我见过的真实错误:

报错信息可能原因解决办法
requests.exceptions.ConnectionError网络不通或接口拒绝访问检查网络;确认URL没写错;降低请求频率
requests.exceptions.Timeout服务器响应过慢增大timeout参数,从5改成10
JSONDecodeError接口返回的不是JSON先打印resp.text看内容;可能被重定向到验证页
KeyError: 'weatherinfo'接口返回结构变化打印完整返回内容,重新定位数据所在的字段
UnicodeEncodeError / 乱码编码问题写入CSV用utf-8-sig;控制台乱码调整终端编码
matplotlib中文方框字体里没中文字符设置rcParams中文字体,见第4.1节
ModuleNotFoundError: pyecharts库没装或装错环境pip install pyecharts,确认和运行脚本是同一Python环境

6.2 接口返回结构变了怎么办

天气接口不是官方商用API,你无法要求它保持永远不变。万一某天运行代码发现 all_data 是空的或者报错KeyError,第一反应不是改代码,而是去验证“现在接口到底返回什么”。我的做法是先写一行最短的请求代码:

import requests print(requests.get("http://www.weather.com.cn/data/sk/101010100.html", headers={"User-Agent": "Mozilla/5.0"}, timeout=5).text)

把返回内容打印出来,看它是JSON、HTML、还是被风控拦截了。JSON里字段还在,只是名字换了,改一下字段名就行;返回的是HTML且里面提示验证,说明触发频率限制了,停一晚上再试;接口彻底失效,就回到第2.1节的方法,去开发者工具重新找一个能用的数据接口。这个方法放之四海而皆准——不管爬什么网站,排查“数据结构变了”永远是先看真实响应,而不是猜。

6.3 可以继续扩展的五个方向

项目跑通之后,扩展就是水到渠成的事。我列几个亲测有效的方向,按难度递增排:

  1. 定时采集:用time.sleep循环或者系统自带的计划任务,每小时跑一次weather_spider.py,积累一个月数据后画气温历史曲线,能看出季节变化。

  2. 接入SQLite:把CSV换成SQLite存储,用sqlite3模块写入,支持按日期查询历史数据,为以后做分析打基础。

  3. 换成其他数据源:把CITY_IDS和URL字段替换成别的公开接口,代码主体不用动。比如有些国外天气API返回的JSON字段是英文,清洗函数里多写几个replace就行。

  4. 做Web展示:用Flask写一个页面,读取CSV或SQLite数据,前端用ECharts动态渲染图表,把整个项目变成一个小型天气数据展示系统。

  5. 预测建模:有了历史温度数据,叠加湿度、风力字段,可以尝试用线性回归或时间序列模型做短期温度预测。爬虫项目到这里就自然延伸到机器学习领域了。

我个人在实际操作中的体会是:这个项目最大的价值不在于“爬天气”本身,而在于帮你建立一套处理真实数据的工作流——从一口一口吃不透的原始数据,到清洗、存储、可视化,每一步都有明确的产出物。做课程设计也好、写技术博客也好、甚至面试讲项目经历也好,这套流程的含金量比单纯背一堆语法高得多。

最后再分享一个小技巧:调试的时候,把时间等字段一起存下来,看似多余,但以后回看数据时能帮你快速定位“这次采集是不是凌晨脚本跑挂了”之类的问题。数据字段多存一点,永远比少存一点更省心。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询