| Day 30 | 综合项目:天气数据综合分析 + 30 天复盘 |

1 阶段知识串讲 —— 把 Day 22~30 串成一张网

是什么?为什么学?

今天是收官日,不学新知识——把 30 天学的所有东西组装成一辆能跑的车:从网络拿数据(Day 26/27)、用表格分析(Day 22/23)、画图(Day 25)、存数据库(Day 28)、做成网页(Day 29)。做完这个项目,你就从”会写脚本”升级成”能独立交付一个小产品”了。如果中间卡住,回头翻对应天数的文档,这本身就是复盘。

底层原理

一句话串法:NumPy 打底 → Pandas 管表 → 数据清洗保质量 → matplotlib 出图 → 爬虫取网页数据 → API 调服务数据 → SQLite 落地存储 → Flask 展示成网页。阶段知识地图:

Day 22  NumPy(数组与向量化运算)────────────┐
Day 23  Pandas(DataFrame 表格分析)──────────┤
Day 24  数据清洗(缺失值/重复值/类型转换)──────┤
Day 25  matplotlib(折线/柱状/散点/饼图)──────┤
Day 26  爬虫(requests + BeautifulSoup)──────┤
Day 27  Web API(GET/POST/JSON 调用)─────────┤
Day 28  SQLite(建表/CRUD/事务/防注入)────────┤
Day 29  Flask(路由/模板/表单/JSON 接口)──────┤
                                        └──→ 综合项目:天气数据综合分析

天气项目把这八样按流水线顺序组装:API 拿数据(Day 27)→ Pandas 分析(Day 23/24)→ 画图(Day 25)→ 入库(Day 28)→ 网页展示(Day 29)——每一步都在用前面某天的知识,缺一环整条链就断

生活类比

做一道完整的菜:买菜(API 取数据)→ 洗菜切菜(Pandas 分析)→ 摆盘(matplotlib 画图)→ 放冰箱冷藏(SQLite 存储)→ 端上桌(Flask 展示)。少了任何一环,这道菜都端不上来。

注意事项总结

每个知识点在本项目里干什么:

  1. **NumPy(Day 22)——数值计算的”引擎”**:Pandas 的底层就是 NumPy——df["tmax"] 取出的每一列本质是 NumPy 数组;df["tmax"].mean()idxmax() 这些统计背后都是 NumPy 在算。你直接写 NumPy 的地方不多,但它支撑着上面所有的分析。
  2. Pandas(Day 23)——分析的主战场pd.DataFrame(data) 把天气数据装进表格;df.shape 看形状、df.head(3) 看样例、describe() 出统计、df.loc[df["tmax"].idxmax()] 找最热一天、nlargest(3, "rain") 找降雨前三。
  3. 数据清洗(Day 24)——保证数据质量resp.raise_for_status() 拦截失败请求、describe() 函数翻译天气代码、INSERT OR IGNORE 去重。真实项目里 80% 的时间在清洗数据
  4. matplotlib(Day 25)——把数字变成图形charts.py 生成温度折线图和降水柱状图;plt.xticks(rotation=30) 防日期重叠、tight_layout 防裁切、savefig 存 PNG、close 释放内存。
  5. 爬虫(Day 26)——从网页拿数据:项目用官方 API,但合规意识和错误处理仍然适用——timeout=10 防卡死、raise_for_status() 检查状态、不频繁请求。
  6. Web API(Day 27)——和服务器对话:**这是项目的”水源”**——weather_data.pyrequests.get + params 发请求,resp.json()["daily"] 取出数据,zip 打包成列表。没有这一步,后面全部是空谈。
  7. SQLite(Day 28)——数据的”仓库”date 做主键、INSERT OR IGNORE 保证同一日期只存一次(幂等:跑两次第二次新增 0 条);load_weather() 读回数据供网页展示;全程参数化查询。
  8. Flask(Day 29)——把成果展示出去/ 路由跑一遍完整流水线,把统计结果传给 report.html 渲染;summary["table"]{% for %} 循环渲染成表格;图片从 /static/ 提供。

项目拆解:五步流水线 → 知识点对照

环节文件用到的知识点来自哪几天在本项目中的作用
1. 数据获取weather_data.pyrequests、params、JSON 解析、状态码、函数Day 27 / 8 / 13从 Open-Meteo 拿到北京 7 天天气,翻译天气代码
2. 数据分析analysis.pyDataFrame、describe、loc、idxmax、nlargestDay 23 / 22统计、找最热一天、降雨前三、平均温度
3. 可视化charts.pyplot、bar、savefig、close、中文字体Day 25生成温度折线图和降水柱状图 PNG
4. 数据存储database.py建表、INSERT OR IGNORE、主键、参数化查询、事务Day 28数据入库且同日期去重(幂等),可反复运行
5. 网页展示app.py + report.html路由、render_template、Jinja2 循环、staticDay 29 / 18把分析结果 + 图表渲染成浏览器报告页

观察这张表:项目的「数据能力」来自 Day 22~28,项目的「出口」来自 Day 29。能讲清这张表,你就真正学会了这 30 天

易错点

  • 错误写法:一口气写完五个文件再运行 → 问题:出问题范围大、难定位 → 正确写法:每完成一个环节就运行一次、验证一次(小步迭代)。
  • 错误写法:找最大值用 df[df["tmax"].max()] → 问题:拿”最大值”去和整列比较,条件永远不成立,返回空 → 正确写法:df.loc[df["tmax"].idxmax()](idxmax 找行号 + loc 取整行)。
  • 错误写法:每刷新一次页面就请求一次外部 API → 问题:慢、费流量、有频率限制,可能 502 → 正确写法:优先从数据库读,没有数据才请求 API 并入库(缓存思路)。

记忆口诀:取数分析画出图,入库展示五步走;一环扣一环,缺一就断链。

2 第 1 步:数据获取(weather_data.py)

是什么?为什么学?

用 Open-Meteo 拿北京 7 天的最高温、最低温、降水、天气代码,返回成列表。这是项目的”水源”——没有这一步,后面全部是空谈。

底层原理

requests.get + params 把经纬度、天数、需要的气象字段发给 Open-Meteo 官方 API;resp.raise_for_status() 拦截失败请求;resp.json()["daily"] 取出 7 天的温度、降水、天气代码;zip 把多个列表打包成一条条记录。

代码演示

# weather_data.py —— 从 Open-Meteo 获取北京 7 天天气
import requests

# 北京经纬度
BEIJING = (39.9042, 116.4074)

def fetch_weather(days=7):
    """返回 [{date, tmax, tmin, rain, code}, ...] 列表"""
    params = {
        "latitude": BEIJING[0],
        "longitude": BEIJING[1],
        "daily": ("temperature_2m_max,temperature_2m_min,"
                  "precipitation_sum,weather_code"),
        "timezone": "Asia/Shanghai",
        "forecast_days": days,
    }
    resp = requests.get("https://api.open-meteo.com/v1/forecast",
                        params=params, timeout=10)
    resp.raise_for_status()
    daily = resp.json()["daily"]

    # weather_code:0 晴,1~3 多云/阴,51+ 雨,71+ 雪(Open-Meteo 官方编码)
    def describe(code):
        if code == 0:
            return "晴"
        if code in (1, 2, 3):
            return "多云"
        if 51 <= code <= 67:
            return "雨"
        if 71 <= code <= 86:
            return "雪"
        return "其它"

    result = []
    for d, tmax, tmin, rain, code in zip(
            daily["time"], daily["temperature_2m_max"],
            daily["temperature_2m_min"], daily["precipitation_sum"],
            daily["weather_code"]):
        result.append({
            "date": d,
            "tmax": tmax,
            "tmin": tmin,
            "rain": rain,
            "weather": describe(code),
        })
    return result

if __name__ == "__main__":
    data = fetch_weather()
    for item in data:
        print(item)

运行结果(示例,数据随当天变化):

{'date': '2026-08-04', 'tmax': 34.1, 'tmin': 25.5, 'rain': 0.4, 'weather': '雨'}
{'date': '2026-08-05', 'tmax': 37.2, 'tmin': 25.6, 'rain': 0.0, 'weather': '多云'}
...

注意事项总结weather_code 是 Open-Meteo 官方天气代码,在 describe 函数里翻译成中文——数据在源头清理好,下游全都省事(Day 24 数据清洗的核心思路 + Day 15 单一职责)。运行成功说明第 1 步完成。

易错点

  • 错误写法:不设 timeout → 问题:网络卡住时程序无限等待 → 正确写法:requests.get(..., timeout=10)
  • 错误写法:不检查状态码直接 resp.json() → 问题:请求失败时解析报错 → 正确写法:先 resp.raise_for_status()
  • 错误写法:天气代码不翻译直接存 → 问题:下游每个环节都要自己翻译一遍 → 正确写法:fetch_weather 返回时已带中文 weather 字段。

记忆口诀:源头先把数据清,下游全都省力气;代码翻译放一处,处处都不用再译。

3 第 2 步:数据分析(analysis.py)

是什么?为什么学?

把数据放进 Pandas DataFrame(Day 22/23 学的),做统计、排序、筛选。这是项目的”分析大脑”。

代码演示

# analysis.py —— 用 Pandas 分析天气数据
import pandas as pd
from weather_data import fetch_weather

def analyze(data):
    """把天气数据转成 DataFrame 并做统计"""
    df = pd.DataFrame(data)
    print("数据形状:", df.shape)
    print("\n前 3 行:")
    print(df.head(3))

    print("\n基本统计:")
    print(df[["tmax", "tmin", "rain"]].describe())

    print("\n最热的一天:")
    hottest = df.loc[df["tmax"].idxmax()]
    print(f"{hottest['date']},最高 {hottest['tmax']}℃")

    print("\n降雨最多的三天:")
    print(df.nlargest(3, "rain")[["date", "rain"]])

    print("\n平均温度(摄氏度,保留 1 位):")
    avg = (df["tmax"] + df["tmin"]) / 2
    print(round(avg.mean(), 1))

    return df

if __name__ == "__main__":
    df = analyze(fetch_weather())

运行结果(示例,数据随当天变化):

数据形状: (7, 5)

前 3 行:
         date  tmax  tmin  rain weather
0  2026-08-04  34.1  25.5   0.4       雨
1  2026-08-05  37.2  25.6   0.0      多云
2  2026-08-06  39.3  27.6   0.0      多云
...
最热的一天:
2026-08-06,最高 39.3℃

注意事项总结df.loc[df["tmax"].idxmax()] 是先找最大值的行号(idxmax),再用 loc 取那一行——Pandas 里最常用的”找极值”套路describe() 出统计、nlargest(3, "rain") 找降雨前三、(df["tmax"] + df["tmin"]) / 2 是向量化计算平均温度。

易错点

  • 错误写法:df[df["tmax"].max()] → 问题:拿”最大值 39.3″和整列比较,没有任何一行”等于”最大值本身,返回空 → 正确写法:df.loc[df["tmax"].idxmax()](先找位置再取行)。
  • 错误写法:忘了 round(avg.mean(), 1) → 问题:平均温度一长串小数 → 正确写法:保留 1 位小数展示。
  • 错误写法:直接在 print 里反复算 df["tmax"].mean() → 问题:重复计算、代码啰嗦 → 正确写法:先用 avg = (df["tmax"] + df["tmin"]) / 2 存变量再用。

记忆口诀:找极值先 idxmax 定位,再用 loc 取整行;Pandas 套路记心头。

4 第 3 步:可视化(charts.py)

是什么?为什么学?

用 matplotlib 生成两张图:温度折线图、降水柱状图,保存成 PNG 供网页展示。图是给”人”看的,这一步让项目有了”门面”。

代码演示

# charts.py —— 生成天气图表
import matplotlib.pyplot as plt

# 中文字体设置(画图脚本必备,见 Day 25)
plt.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei"]
plt.rcParams["axes.unicode_minus"] = False

def make_charts(df):
    """根据 DataFrame 生成两张图:temperature.png 和 rain.png"""
    dates = df["date"].tolist()

    # 图 1:最高/最低温折线图
    plt.figure(figsize=(8, 4))
    plt.plot(dates, df["tmax"], marker="o", label="最高温")
    plt.plot(dates, df["tmin"], marker="s", label="最低温")
    plt.title("北京未来 7 天温度走势")
    plt.xlabel("日期")
    plt.ylabel("温度(℃)")
    plt.legend()
    plt.grid(True, linestyle="--", alpha=0.5)
    plt.xticks(rotation=30)      # 日期斜着显示,避免重叠
    plt.tight_layout()
    plt.savefig("temperature.png", dpi=150)
    plt.close()                  # 关闭画布,释放内存

    # 图 2:降水量柱状图
    plt.figure(figsize=(8, 4))
    plt.bar(dates, df["rain"], color="steelblue")
    plt.title("北京未来 7 天降水量")
    plt.xlabel("日期")
    plt.ylabel("降水量(mm)")
    plt.xticks(rotation=30)
    plt.tight_layout()
    plt.savefig("rain.png", dpi=150)
    plt.close()

    print("已生成 temperature.png 和 rain.png")

if __name__ == "__main__":
    import pandas as pd
    from weather_data import fetch_weather
    make_charts(pd.DataFrame(fetch_weather()))

运行结果:

已生成 temperature.png 和 rain.png

注意事项总结工程化注意——生成图表用 plt.close() 关闭画布,否则在脚本里多次 plt.figure() 会累计内存。图片保存在和 charts.py 相同的目录(project/backend/ 下),第 5 步的 Flask 直接引用(需挪到 static/)。

易错点

  • 错误写法:画图脚本少了中文字体设置 → 问题:图表中文显示成方框 → 正确写法:开头加 plt.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei"]
  • 错误写法:plt.figure() 后不 plt.close() → 问题:多次画图内存累计 → 正确写法:savefigplt.close()
  • 错误写法:日期标签横排 → 问题:7 个日期挤在一起看不清 → 正确写法:plt.xticks(rotation=30) 斜着显示 + tight_layout 防裁切。

记忆口诀:中文字体先设好,画完记得 close 掉;日期斜放不重叠,savefig 存图网页要。

5 第 4 步:数据存储(database.py)

是什么?为什么学?

把天气数据存进 SQLite,关键点:同一日期只存一次(重复入库会跳过)。用 Day 28 学的参数化查询和事务。这一步让数据”沉淀”下来,不依赖每次现抓。

代码演示

# database.py —— 天气数据存入 SQLite
import sqlite3

DB_FILE = "weather.db"

def init_db():
    conn = sqlite3.connect(DB_FILE)
    conn.execute("""
    CREATE TABLE IF NOT EXISTS daily_weather (
        date TEXT PRIMARY KEY,     -- 日期做主键,天然去重
        tmax REAL,
        tmin REAL,
        rain REAL,
        weather TEXT
    )
    """)
    conn.commit()
    conn.close()

def save_weather(data):
    """把天气数据写入数据库;同一日期已存在则跳过(INSERT OR IGNORE)"""
    conn = sqlite3.connect(DB_FILE)
    inserted = 0
    for item in data:
        cur = conn.execute(
            "INSERT OR IGNORE INTO daily_weather "
            "(date, tmax, tmin, rain, weather) VALUES (?, ?, ?, ?, ?)",
            (item["date"], item["tmax"], item["tmin"],
             item["rain"], item["weather"]),
        )
        inserted += cur.rowcount      # 0 表示已存在,跳过
    conn.commit()
    conn.close()
    return inserted

def load_weather():
    """从数据库读回全部数据(用于网页展示)"""
    conn = sqlite3.connect(DB_FILE)
    rows = conn.execute(
        "SELECT date, tmax, tmin, rain, weather "
        "FROM daily_weather ORDER BY date"
    ).fetchall()
    conn.close()
    return [
        {"date": r[0], "tmax": r[1], "tmin": r[2], "rain": r[3], "weather": r[4]}
        for r in rows
    ]

if __name__ == "__main__":
    from weather_data import fetch_weather
    init_db()
    new = save_weather(fetch_weather())
    print(f"新增 {new} 条(重复日期会自动跳过)")
    print("数据库中现有数据:")
    for row in load_weather():
        print(row)

运行结果(示例):

新增 7 条(重复日期会自动跳过)
数据库中现有数据:
{'date': '2026-08-04', 'tmax': 34.1, 'tmin': 25.5, 'rain': 0.4, 'weather': '雨'}
...

注意事项总结INSERT OR IGNORE 配合主键 date:日期已存在就忽略。再运行一次,新增是 0 条——这就是”幂等”,重复执行不产生副作用。相比每次先 SELECT 查重,这一行 SQL 更简洁可靠。全程参数化查询防注入 + commit() 事务。

易错点

  • 错误写法:直接 INSERT 撞了主键 → 问题:报 sqlite3.IntegrityError: UNIQUE constraint failed → 正确写法:用 INSERT OR IGNORE,或先查重再插入。
  • 错误写法:忘了 conn.commit() → 问题:数据没真正写入文件 → 正确写法:写操作后 conn.commit()
  • 错误写法:SQL 里字符串拼接 → 问题:SQL 注入风险 → 正确写法:一律 ? 占位 + 元组传参。

记忆口诀:主键天然去重,IGNORE 跳过重复;幂等跑两遍,新增仍是零。

6 第 5 步:网页展示(app.py + report.html)

是什么?为什么学?

最后用 Flask 把分析结果和两张图展示成网页(端口 2050)。这一步让整个项目的成果变成浏览器里的一页报告。

代码演示

# app.py —— Flask 展示天气分析报告
from flask import Flask, render_template
import pandas as pd
from weather_data import fetch_weather
from analysis import analyze
from charts import make_charts
from database import init_db, save_weather, load_weather

app = Flask(__name__)

def run_pipeline():
    """执行完整流水线:获取 -> 分析 -> 画图 -> 入库 -> 返回数据"""
    data = fetch_weather()
    df = analyze(data)
    make_charts(df)
    init_db()
    save_weather(data)
    return df

@app.route("/")
def report():
    # 首次访问自动跑一遍流水线;也可以改成从数据库读
    df = run_pipeline()

    hottest = df.loc[df["tmax"].idxmax()]
    avg_temp = round(((df["tmax"] + df["tmin"]) / 2).mean(), 1)
    total_rain = round(df["rain"].sum(), 1)

    summary = {
        "days": len(df),
        "avg_temp": avg_temp,
        "total_rain": total_rain,
        "hottest_date": hottest["date"],
        "hottest_max": hottest["tmax"],
        "table": df.to_dict("records"),   # DataFrame 转成列表给模板用
    }
    return render_template("report.html", summary=summary)

if __name__ == "__main__":
    app.run(host="127.0.0.1", port=2050, debug=True)

模板 templates/report.html 要点:数据卡片(平均温度 / 总降水量 / 最热一天)+ 每日天气明细表格({% for row in summary["table"] %} 循环)+ 两张图(<img src="/static/temperature.png">)。

注意事项总结:Flask 默认从 static/ 目录提供图片,所以把两张图挪过去:

# 在 project/backend 下执行
mkdir static
move temperature.png rain.png static/

启动:

cd project/backend
python app.py

浏览器打开 http://127.0.0.1:2050/ 就能看到完整的分析报告。升级挑战:把 run_pipeline 改成”优先从数据库读,没有数据才去请求 API”;或加 ?city= 参数支持多个城市。

易错点

  • 错误写法:图表保存后网页显示 404 → 问题:Flask 默认只从 static/ 目录提供静态文件,而图在根目录 → 正确写法:把 PNG 挪进 static/,模板路径写 /static/...
  • 错误写法:每次访问页面都请求外部 API → 问题:慢、费流量、可能 502 → 正确写法:优先 load_weather() 从数据库读,没有才请求并入库。
  • 错误写法:move 命令在 PowerShell 不识别 → 问题:命令执行失败 → 正确写法:用 mv temperature.png rain.png static/(Git Bash)或直接在文件管理器拖动。

记忆口诀:静态图片放 static,网页才能找得到;数据先读库里存,省时省力不怕断。

7 30 天复盘清单 —— 查漏补缺

是什么?为什么学?

复盘是今天最重要的事:对照清单逐条打勾,勾不上的回去重看对应天数的文档。四个阶段的产出递进:阶段一「会写脚本」→ 阶段二「会封装模块」→ 阶段三「会设计类与用第三方库」→ 阶段四「能交付数据产品」。

注意事项总结

四个阶段自查清单:

  1. 语法基础(Day 1~7):变量与类型转换、if / elif / else 与逻辑运算、for / while 循环与 break / continue、字符串方法、列表/元组/字典/集合的增删改查。
  2. 函数与进阶(Day 8~14):函数定义与参数(默认值/关键字/可变)、模块与包(import__main__)、文件读写与 CSV/JSON、异常处理(try / except / else / finally)、f-string。
  3. 面向对象与标准库(Day 15~21):类与对象、__init__、实例/类/静态方法、继承封装多态、魔法方法、os/pathlib/datetimepip install、列表推导式与生成器。
  4. 数据分析与实战(Day 22~30):Pandas(DataFrame 创建、筛选/统计/排序)、matplotlib(四种图 + 保存)、requests + BeautifulSoup(爬数据 + 合规)、Web API(GET/POST/JSON)、SQLite(建表/CRUD/防注入/事务)、Flask(路由/模板/表单/JSON 接口)、综合项目全流程跑通。

易错点

  • 错误写法:复盘只”看”不”动手” → 问题:眼睛会了手不会,勾上也没用 → 正确写法:勾不上的条目回去重做对应天数的练习
  • 错误写法:项目做不出来就硬扛今天 → 问题:浪费一天还打击信心 → 正确写法:项目做不出来往往不是今天的问题,而是前面某天的基础没打牢,回头翻对应天数的今日总结。
  • 错误写法:以为”会做题”就是”能交付” → 问题:只懂知识不懂组装 → 正确写法:对照项目拆解表,能讲清每个环节用到了哪几天的哪些知识点。

记忆口诀:四个阶段递进走,脚本到产品一条线;勾不上的回去补,能讲清表才算完。

8 后续进阶路线 —— 30 天只是起点

是什么?为什么学?

30 天只是起点。按兴趣选一个方向深入,每个方向都给出先学什么、再做什么

注意事项总结

五个方向:

  1. 方向一:自动化办公 —— 学习 openpyxl(Excel)、python-docx(Word)、PyPDF2(PDF)、smtplib(邮件);练手批量整理成绩单、自动生成周报、批量重命名文件。
  2. 方向二:数据分析 —— 学习 Pandas 进阶(groupby / merge / 透视表)、matplotlib + seabornnumpy;练手分析 Kaggle 真实数据集,出可视化报告。
  3. 方向三:Web 开发 —— 学习 Flask 进阶(ORM SQLAlchemy、用户登录、部署)或 Django;练手把 day29 天气网页升级成”用户系统 + 收藏城市”并部署。
  4. 方向四:爬虫 —— 学习 scrapy 框架、Selenium(动态网页)、反爬应对与合规边界;练手爬公开资讯站点的分类列表(务必遵守 robots.txt)。
  5. 方向五:人工智能 —— 前置 Python + numpy 矩阵运算 + 数学基础(线性代数、概率论);学习 scikit-learnpytorch;练手房价预测、手写数字识别(MNIST)。

通用建议

  1. 项目驱动:每学一个新库,立刻做一个能跑的小项目,别只看文档。
  2. Git 与代码托管:把代码放到 GitHub,养成版本管理习惯(找一天补上 Git)。
  3. 坚持写代码:每天至少 30 分钟,算法题网站(LeetCode 简单题)练手感。
  4. 学会提问:报错先自己搜(复制报错信息到搜索引擎),搜不到再问人。
  5. 写博客记录:把学到的写成笔记,输出是最好的巩固。

易错点

  • 错误写法:五个方向全都想学 → 问题:贪多嚼不烂,一个都学不深 → 正确写法:按兴趣和职业方向选一个,先学进去再扩展。
  • 错误写法:学新库只看文档不写代码 → 问题:看完就忘 → 正确写法:项目驱动,学一个做一个能跑的小项目。
  • 错误写法:AI 方向基础没打牢就硬上 → 问题:数学和矩阵不过关,代码全是抄 → 正确写法:先补 NumPy 和数学基础再进 AI。

记忆口诀:三十天是起点不是终点,选一个方向深挖;项目驱动写博客,每天半小时练手。

今日总结

把 30 天学的知识组装成五步流水线:API 获取 → Pandas 分析 → matplotlib 可视化 → SQLite 存储 → Flask 展示,五个环节全部跑通 每个环节独立成文件(weather_data / analysis / charts / database / app),每步都能单独运行验证(if __name__ == "__main__") 阶段知识地图:NumPy 打底 → Pandas 管表 → 数据清洗保质量 → matplotlib 出图 → 爬虫取网页 → API 调服务 → SQLite 落地 → Flask 展示,一环扣一环 幂等入库:INSERT OR IGNORE + 主键去重,重复运行新增 0 条 图表 404 排查:Flask 静态文件必须在 static/ 目录 网页 http://127.0.0.1:2050/ 展示完整分析报告(数据卡片 + 明细表格 + 两张图) 30 天复盘清单查漏补缺:四个阶段(语法基础 / 函数进阶 / 面向对象 / 数据分析实战)逐项打勾 选定一个进阶方向:自动化办公 / 数据分析 / Web 开发 / 爬虫 / AI,写下下一步学习计划

报错原因修复
ModuleNotFoundError: No module named 'pandas'没安装 Pandaspip install pandas(第 2 步需要)
网页上图片不显示(404)图片没在 static/ 目录,或路径不对确认 project/backend/static/temperature.png 存在,模板路径写 /static/...
页面访问很慢或报 502每次访问都请求 Open-Meteo,网络慢或失败改成”数据库有数据就不请求 API”;加 timeout
图表中文显示成方框画图脚本少了中文字体设置charts.py 开头加 plt.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei"]
sqlite3.IntegrityError: UNIQUE constraint failed直接 INSERT 撞了主键INSERT OR IGNORE,或先查重再插入
导入自己写的模块报错(No module named ‘weather_data’)运行目录不对project/backend 目录下运行 python app.py,让脚本和模块在同一目录
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇