ProxyForge

Заметки о разработке, инструментах и работе с данными.

Воскресный парсер прогноза погоды

Понадобился аккуратный набор данных: температура и осадки по моему городу за последние пять лет, по дням. Бесплатные API дают либо текущее, либо месячный history с лимитом. Сел собирать самому в воскресенье.

Идея простая

  1. Берём публичный архив наблюдений (rp5, синоптики и пр.).
  2. Скачиваем CSV постранично.
  3. Кладём в локальный SQLite, чтобы потом удобно SELECT-ать.
  4. Каждый день обновляем последний слой инкрементом.

Что получилось

import httpx, sqlite3, csv, io
from datetime import date, timedelta

DB = sqlite3.connect("weather.db")
DB.execute("""CREATE TABLE IF NOT EXISTS obs (
    day TEXT PRIMARY KEY,
    t_avg REAL, t_min REAL, t_max REAL,
    precip REAL
)""")

def fetch(d: date) -> bytes:
    url = f"https://example-archive.local/csv?date={d.isoformat()}"
    return httpx.get(url, timeout=10).content

def upsert(d: date, row: dict) -> None:
    DB.execute(
        "INSERT INTO obs VALUES (?,?,?,?,?) "
        "ON CONFLICT(day) DO UPDATE SET "
        "t_avg=excluded.t_avg, t_min=excluded.t_min, "
        "t_max=excluded.t_max, precip=excluded.precip",
        (d.isoformat(), row["t_avg"], row["t_min"], row["t_max"], row["precip"]),
    )

Грабли

Что стало возможным

Самое приятное — простые SQL-вопросы на готовых данных:

SELECT strftime('%Y-%m', day) AS month,
       AVG(t_avg) AS t,
       SUM(precip) AS rain
FROM obs
WHERE day >= date('now', '-5 years')
GROUP BY month
ORDER BY month;

График по результату я уже строил в обычном matplotlib. Никакой хитрости — просто полезный SQLite на 30 МБ, на котором можно проверять любую гипотезу за секунды.