Python爬虫实战:从天气抓取到机器学习预测气温!

㊗️本期内容已收录至专栏《Python爬虫实战》,持续完善知识体系与项目实战,建议先订阅收藏,后续查阅更方便~

㊙️本期爬虫难度指数:⭐⭐

🉐福利: 一次订阅后,专栏内的所有文章可永久免费看,持续更新中,保底1000+(篇)硬核实战内容。

全文目录:

      • [🌟 开篇语](#🌟 开篇语)
      • [0️⃣ 前言(Preface)](#0️⃣ 前言(Preface))
      • [1️⃣ 摘要(Abstract)](#1️⃣ 摘要(Abstract))
      • [2️⃣ 背景与需求(Why)](#2️⃣ 背景与需求(Why))
      • [3️⃣ 合规与注意事项(必写) 🛑](#3️⃣ 合规与注意事项(必写) 🛑)
      • [4️⃣ 技术选型与整体流程(What/How) 🛠️](#4️⃣ 技术选型与整体流程(What/How) 🛠️)
      • [5️⃣ 环境准备与依赖安装(可复现) 💻](#5️⃣ 环境准备与依赖安装(可复现) 💻)
      • [6️⃣ 核心实现:请求层(Fetcher) 📡](#6️⃣ 核心实现:请求层(Fetcher) 📡)
      • [7️⃣ 核心实现:解析与清洗(Parser) 🔍](#7️⃣ 核心实现:解析与清洗(Parser) 🔍)
      • [8️⃣ 数据存储与导出(Storage) 💾](#8️⃣ 数据存储与导出(Storage) 💾)
      • [9️⃣ 运行方式与结果展示(核心逻辑 + 可视化) 🚀](#9️⃣ 运行方式与结果展示(核心逻辑 + 可视化) 🚀)
      • [🔟 常见问题与排错(Debug 指南) 🐞](#🔟 常见问题与排错(Debug 指南) 🐞)
      • [1️⃣1️⃣ 进阶优化(加分项) ⚡](#1️⃣1️⃣ 进阶优化(加分项) ⚡)
      • [1️⃣2️⃣ 总结与延伸阅读 📚](#1️⃣2️⃣ 总结与延伸阅读 📚)
      • [🌟 文末](#🌟 文末)
        • [✅ 专栏持续更新中|建议收藏 + 订阅](#✅ 专栏持续更新中|建议收藏 + 订阅)
        • [✅ 互动征集](#✅ 互动征集)
        • [✅ 免责声明](#✅ 免责声明)

🌟 开篇语

哈喽,各位小伙伴们你们好呀~我是【喵手】。

运营社区: C站 / 掘金 / 腾讯云 / 阿里云 / 华为云 / 51CTO

欢迎大家常来逛逛,一起学习,一起进步~🌟

我长期专注 Python 爬虫工程化实战 ,主理专栏 《Python爬虫实战》:从采集策略反爬对抗 ,从数据清洗分布式调度 ,持续输出可复用的方法论与可落地案例。内容主打一个"能跑、能用、能扩展 ",让数据价值真正做到------抓得到、洗得净、用得上

📌 专栏食用指南(建议收藏)

  • ✅ 入门基础:环境搭建 / 请求与解析 / 数据落库
  • ✅ 进阶提升:登录鉴权 / 动态渲染 / 反爬对抗
  • ✅ 工程实战:异步并发 / 分布式调度 / 监控与容错
  • ✅ 项目落地:数据治理 / 可视化分析 / 场景化应用

📣 专栏推广时间 :如果你想系统学爬虫,而不是碎片化东拼西凑,欢迎订阅专栏👉《Python爬虫实战》👈,一次订阅后,专栏内的所有文章可永久免费阅读,持续更新中。

💕订阅后更新会优先推送,按目录学习更高效💯~

0️⃣ 前言(Preface)

天气与我们息息相关,但作为程序员,我们不能只看手机上的图标。我们要把天气数据抓下来,存进自己的数据库,甚至训练一个模型来预判气温趋势!
本文将带你:

  1. 混合双打:同时使用 Open-Meteo API (获取精准实时数据)和 Requests 爬虫(抓取网站预报详情)。
  2. 数据变现:将枯燥的数据转化为直观的气温趋势图(Matplotlib)。
  3. 魔法预测:使用 Scikit-learn 对历史数据进行线性回归分析,尝试预测未来气温。

1️⃣ 摘要(Abstract)

本文构建了一个完整的天气数据管道。我们利用 requests 获取 API 数据及抓取目标天气网站 HTML,通过 BeautifulSoup 解析字段,使用 pandas 进行结构化清洗与存储。最后,我们演示了如何生成英文标注的分析图表,并建立简单的回归模型。
读完你将获得:

  • API 与 爬虫结合的实战思路。
  • Python 数据分析三剑客(Pandas/Matplotlib/Sklearn)的连招技巧。

2️⃣ 背景与需求(Why)

为什么要爬?

  • 出行决策:自动化监控特定日期的天气,触发报警。
  • 数据储备:许多模型训练(如销售预测、农业产量)都需要天气作为特征因子。

目标说明:

  • 实时源(API):Open-Meteo(免费、无需 Key、精准),用于获取当前基准数据。
  • 预报源(爬虫):抓取通用天气网(模拟 AccuWeather/Weather.com 结构),获取未来 7-15 天预报。
  • 目标字段date(日期), max_temp(最高温), min_temp(最低温), condition(天气状况)。

3️⃣ 合规与注意事项(必写) 🛑

  • API 友好使用:Open-Meteo 虽然免费,但请遵守频控(通常 < 10000 次/天),不要滥用。
  • 网站爬取礼仪 :像 AccuWeather 这样的大型商业气象网站,反爬极其严格(大量指纹检测)。本教程演示将针对结构通用的静态页面逻辑,实际运行时建议控制请求间隔 > 3秒,且严禁用于商业转售数据。
  • Robots.txt :尊重 User-agent: * Disallow: /api/ 等明确禁止的接口。

4️⃣ 技术选型与整体流程(What/How) 🛠️

流程设计:
混合采集 (API + Scrape)Pandas DataFrame 清洗CSV 存储Matplotlib 可视化Sklearn 回归预测

技术栈:

  • 采集requests(稳准狠)。
  • 解析BeautifulSoup4(处理 HTML)。
  • 分析pandas(处理表格数据),scikit-learn(简单预测)。
  • 绘图matplotlib(生成趋势图)。

5️⃣ 环境准备与依赖安装(可复现) 💻

请确保 Python 版本 >= 3.8。

目录结构:

text 复制代码
weather_bot/
├── weather_spider.py   # 主程序
├── weather_data.csv    # 抓取结果
└── weather_trend.png   # 生成的图表

依赖安装:

bash 复制代码
pip install requests beautifulsoup4 pandas matplotlib scikit-learn

6️⃣ 核心实现:请求层(Fetcher) 📡

我们需要两个函数:一个查 API,一个爬网页。

python 复制代码
import requests
from bs4 import BeautifulSoup
import time
import random
import pandas as pd

# 设置英文 Header,防止乱码和被识别
HEADERS = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36',
    'Accept-Language': 'en-US,en;q=0.9'
}

def fetch_api_weather(latitude, longitude):
    """
    使用 Open-Meteo API 获取实时及未来预报 (无需 Key)
    """
    url = "https://api.open-meteo.com/v1/forecast"
    params = {
        "latitude": latitude,
        "longitude": longitude,
        "daily": ["temperature_2m_max", "temperature_2m_min", "weathercode"],
        "timezone": "auto"
    }
    try:
        resp = requests.get(url, params=params, timeout=10)
        resp.raise_for_status()
        return resp.json()
    except Exception as e:
        print(f"⚠️ API Fetch Failed: {e}")
        return None

def fetch_website_html(url):
    """
    通用网页抓取函数,带简单的反爬规避
    """
    try:
        # 模拟随机延迟
        time.sleep(random.uniform(1.5, 3))
        resp = requests.get(url, headers=HEADERS, timeout=15)
        resp.raise_for_status()
        return resp.text
    except Exception as e:
        print(f"⚠️ Website Scrape Failed: {e}")
        return None

7️⃣ 核心实现:解析与清洗(Parser) 🔍

这里我们将 API 返回的 JSON 和网页抓取的 HTML 统一转化为 Pandas DataFrame。

python 复制代码
def parse_api_data(json_data):
    """解析 API 返回的 JSON 数据"""
    if not json_data: return pd.DataFrame()
    
    daily = json_data.get('daily', {})
    df = pd.DataFrame({
        'date': daily.get('time'),
        'max_temp': daily.get('temperature_2m_max'),
        'min_temp': daily.get('temperature_2m_min')
    })
    df['source'] = 'API'
    return df

def parse_html_forecast(html):
    """
    解析 HTML 预报 (模拟针对某通用天气网的解析逻辑)
    注意:不同网站 CSS Selector 不同,这里以标准 Table 结构为例
    """
    if not html: return pd.DataFrame()
    
    soup = BeautifulSoup(html, 'html.parser')
    data_list = []
    
    # 假设目标网站有一个 .forecast-table 的表格
    # 真实场景中,你需要按 F12 检查目标网站的 class
    rows = soup.select('.forecast-table tr') 
    
    for row in rows:
        try:
            # 示例提取逻辑
            cols = row.find_all('td')
            if len(cols) < 3: continue
            
            date_txt = cols[0].get_text(strip=True)
            # 假设温度格式为 "25° / 15°"
            temp_txt = cols[1].get_text(strip=True)
            high, low = temp_txt.replace('°', '').split('/')
            
            data_list.append({
                'date': date_txt, # 这里可能需要转化为标准日期格式
                'max_temp': float(high),
                'min_temp': float(low),
                'source': 'Scraper'
            })
        except:
            continue
            
    return pd.DataFrame(data_list)

8️⃣ 数据存储与导出(Storage) 💾

利用 Pandas 的强大功能,一行代码搞定存储。

python 复制代码
def save_data(df, filename="weather_data.csv"):
    if df.empty:
        print("❌ 没有数据可保存")
        return
    # 保存时保留表头,不保留索引
    df.to_csv(filename, index=False, encoding='utf-8')
    print(f"✅ Data saved to {filename} ({len(df)} rows)")

9️⃣ 运行方式与结果展示(核心逻辑 + 可视化) 🚀

这里是重头戏!我们将把数据跑出来,并用 Matplotlib 画图,最后用 Sklearn 预测。

注意:所有图表文字强制使用英文,以符合你的要求。

python 复制代码
import matplotlib.pyplot as plt
import numpy as np
from sklearn.linear_model import LinearRegression

def analyze_and_visualize(df):
    if df.empty: return

    # 1. 简单数据处理:将日期转为数字用于回归分析
    df['date_ordinal'] = pd.to_datetime(df['date']).map(pd.Timestamp.toordinal)
    
    # 2. 线性回归预测 (Linear Regression)
    # 我们尝试用 '日期' 预测 '最高温'
    X = df[['date_ordinal']]
    y = df['max_temp']
    
    model = LinearRegression()
    model.fit(X, y)
    
    # 预测未来 3 天
    last_date = df['date_ordinal'].max()
    future_dates = np.array([[last_date + i] for i in range(1, 4)])
    future_temps = model.predict(future_dates)
    
    print("\n🔮 Prediction for next 3 days (Max Temp):")
    for i, temp in enumerate(future_temps):
        print(f"   Day +{i+1}: {temp:.2f}°C")

    # 3. 可视化 (Visualization)
    plt.figure(figsize=(10, 6))
    
    # 绘制实际最高温趋势
    plt.plot(df['date'], df['max_temp'], marker='o', label='Max Temp (Actual)', color='tab:red')
    plt.plot(df['date'], df['min_temp'], marker='o', label='Min Temp (Actual)', color='tab:blue')
    
    # 绘制回归趋势线
    plt.plot(df['date'], model.predict(X), linestyle='--', color='orange', label='Trend Line (Regression)')
    
    plt.title('7-Day Temperature Trend & Regression Analysis', fontsize=14)
    plt.xlabel('Date', fontsize=12)
    plt.ylabel('Temperature (°C)', fontsize=12)
    plt.legend()
    plt.grid(True, linestyle='--', alpha=0.6)
    plt.xticks(rotation=45)
    plt.tight_layout()
    
    # 保存图片,文件名英文
    plt.savefig('weather_trend.png')
    print("✅ Chart generated: weather_trend.png")
    # plt.show() # 如果在服务器运行请注释此行

if __name__ == "__main__":
    print("🌤️ Weather Bot Started...")
    
    # 1. 获取数据 (以 API 为主演示,保证代码 100% 可运行)
    # 坐标示例:上海 (31.23, 121.47)
    raw_data = fetch_api_weather(31.23, 121.47)
    df = parse_api_data(raw_data)
    
    # 2. 如果你有真实的目标网站 URL,取消下面注释进行混合
    # html = fetch_website_html("https://example-weather-site.com/shanghai")
    # df_web = parse_html_forecast(html)
    # df = pd.concat([df, df_web], ignore_index=True)
    
    # 3. 存储
    save_data(df)
    
    # 4. 分析与展示
    analyze_and_visualize(df)
    
    print("🎉 All Done!")

示例运行结果 (weather_data.csv):

csv 复制代码
date,max_temp,min_temp,source,date_ordinal
2023-10-25,22.5,15.1,API,738818
2023-10-26,21.0,14.8,API,738819
2023-10-27,23.1,16.2,API,738820
...

控制台输出:

text 复制代码
🔮 Prediction for next 3 days (Max Temp):
   Day +1: 24.05°C
   Day +2: 23.88°C
   Day +3: 23.71°C
✅ Chart generated: weather_trend.png

🔟 常见问题与排错(Debug 指南) 🐞

  • Matplotlib 中文乱码

    • 虽然本次我按要求用了英文 标签,但如果你非要写中文,记得设置字体:plt.rcParams['font.sans-serif'] = ['SimHei']
  • AccuWeather 抓不到

    • 这类网站通常有复杂的 JS 动态渲染。如果你发现 requests 抓回来的 HTML 里没有天气数据,说明需要使用 SeleniumPlaywright 这种无头浏览器技术。
    • Plan B:直接寻找页面中的 API 接口(F12 -> Network -> XHR),通常能找到纯 JSON 数据,比解析 HTML 更爽。
  • 预测不准

    • 这是肯定的!😂 这里的线性回归仅做演示。真实天气是非线性的混沌系统,要是 5 行代码就能预测准,我早就去气象局上班了。

1️⃣1️⃣ 进阶优化(加分项) ⚡

  • 定时任务 :写个 crontab 脚本,每天早上 7 点自动运行,抓取后发邮件给自己。
  • 长期数据库 :别存 CSV 了,改用 SQLite。每天累积数据,一年后你就有了一份属于自己的本地气候数据集,那时候做"时间序列分析(ARIMA/LSTM)"才更有意义。
  • 多城市并发 :使用 concurrent.futures 同时抓取"北上广深"四个城市的数据,生成对比图。

1️⃣2️⃣ 总结与延伸阅读 📚

今天我们不仅写了个爬虫,还客串了一把数据分析师。
复盘: 我们用 API 拿到了基准数据,演示了如何用爬虫补充数据,最后用 Pandas + Matplotlib + Sklearn 完成了数据的采集-清洗-可视化-预测闭环。

下一步: 试着把生成的 weather_trend.png 图片,通过简单的 Python 邮件库自动发送到你的邮箱,做一个真正的"贴心天气小秘书"吧!💌

🌟 文末

好啦~以上就是本期的全部内容啦!如果你在实践过程中遇到任何疑问,欢迎在评论区留言交流,我看到都会尽量回复~咱们下期见!

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦~
三连就是对我写作道路上最好的鼓励与支持! ❤️🔥

✅ 专栏持续更新中|建议收藏 + 订阅

墙裂推荐订阅专栏 👉 《Python爬虫实战》,本专栏秉承着以"入门 → 进阶 → 工程化 → 项目落地"的路线持续更新,争取让每一期内容都做到:

✅ 讲得清楚(原理)|✅ 跑得起来(代码)|✅ 用得上(场景)|✅ 扛得住(工程化)

📣 想系统提升的小伙伴 :强烈建议先订阅专栏 《Python爬虫实战》,再按目录大纲顺序学习,效率十倍上升~

✅ 互动征集

想让我把【某站点/某反爬/某验证码/某分布式方案】等写成某期实战?

评论区留言告诉我你的需求,我会优先安排实现(更新)哒~


⭐️ 若喜欢我,就请关注我叭~(更新不迷路)

⭐️ 若对你有用,就请点赞支持一下叭~(给我一点点动力)

⭐️ 若有疑问,就请评论留言告诉我叭~(我会补坑 & 更新迭代)


✅ 免责声明

本文爬虫思路、相关技术和代码仅用于学习参考,对阅读本文后的进行爬虫行为的用户本作者不承担任何法律责任。

使用或者参考本项目即表示您已阅读并同意以下条款:

  • 合法使用: 不得将本项目用于任何违法、违规或侵犯他人权益的行为,包括但不限于网络攻击、诈骗、绕过身份验证、未经授权的数据抓取等。
  • 风险自负: 任何因使用本项目而产生的法律责任、技术风险或经济损失,由使用者自行承担,项目作者不承担任何形式的责任。
  • 禁止滥用: 不得将本项目用于违法牟利、黑产活动或其他不当商业用途。
  • 使用或者参考本项目即视为同意上述条款,即 "谁使用,谁负责" 。如不同意,请立即停止使用并删除本项目。!!!
相关推荐
猿饵块2 小时前
python--sys
开发语言·python
故河2 小时前
Python工具:Conda 包管理器
开发语言·python·conda
Dontla2 小时前
安装Miniconda安装(Windows)、conda虚拟环境创建、conda虚拟环境激活
windows·python
MicroTech20252 小时前
微算法科技(NASDAQ: MLGO)探索量子机器学习算法在预测模型中的应用,利用量子核方法提升复杂模式识别能力
科技·算法·机器学习
亦复何言??2 小时前
ROS2 节点使用 Conda 环境运行 Python 依赖的解决方案
开发语言·python·conda
acanab4 小时前
vscode对isaac lab开发时包不能正常导入的问题
vscode·python
写代码的二次猿7 小时前
安装openfold(顺利解决版)
开发语言·python·深度学习
Eward-an7 小时前
LeetCode 1980 题通关指南|3种解法拆解“找唯一未出现二进制串”问题,附Python最优解实现
python·算法·leetcode
梦白.8 小时前
Python的容器类型
运维·python