A Weekend Log of Istanbul's Weekend Water Cuts

这篇内容暂时只有 English 版本,以下是原文。

Every Saturday morning for the past three months, the tap in my Kadıköy apartment has run dry between roughly 09:00 and 13:00. İSKİ publishes planned outage notices, but they’re buried in a PDF that changes URL every week. I wanted a local log to see if the pattern was real — and to know when to fill the kettle.

I wrote a small scraper that runs on a Raspberry Pi Zero 2 W sitting on my shelf. It hits the İSKİ “planlı su kesintisi” page every six hours, pulls the table with BeautifulSoup, and appends rows to a SQLite file. The whole thing is about 40 lines.

import requests, sqlite3, hashlib
from bs4 import BeautifulSoup
from datetime import datetime

URL = "https://www.iski.istanbul/web/tr-TR/ariza-kesinti"
HEADERS = {"User-Agent": "Mozilla/5.0 (compatible; ISKI-log/0.1)"}

def fetch():
    r = requests.get(URL, headers=HEADERS, timeout=30)
    r.raise_for_status()
    return r.text

def parse(html):
    soup = BeautifulSoup(html, "html.parser")
    rows = []
    for tr in soup.select("table tr"):
        cells = [td.get_text(strip=True) for td in tr.find_all("td")]
        if len(cells) < 4:
            continue
        key = hashlib.md5("|".join(cells).encode()).hexdigest()
        rows.append((key, cells[0], cells[1], cells[2], cells[3], datetime.utcnow().isoformat()))
    return rows

def save(rows):
    con = sqlite3.connect("/home/pi/iski.db")
    con.executemany("""
        INSERT OR IGNORE INTO cuts (hash, ilce, mahalle, start, end, seen_at)
        VALUES (?, ?, ?, ?, ?, ?)
    """, rows)
    con.commit()
    con.close()

if __name__ == "__main__":
    save(parse(fetch()))

Why SQLite and a hash? The İSKİ table has no stable ID per row, and the same outage can appear on consecutive fetches. Hashing the visible cells lets me ignore duplicates without tracking a moving cursor. The Pi is headless; I check it with sqlite3 iski.db 'select * from cuts order by seen_at desc limit 5' over SSH. No dashboard, no alerts — I just query it when I’m curious.

This breaks if İSKİ changes the table markup or adds a CAPTCHA. It also misses short-notice cuts (ariza) that never make it to the planned page. I learned that last one the hard way: a burst pipe left us without water for six hours while my log showed nothing. If you rely on this for planning, you’ll still get surprised. Also, the page sometimes returns a generic error page with HTTP 200, so the scraper happily saves zero rows. I added a check for len(rows) == 0 and a log line, but it still runs blind.

What’s your experience with Turkish utility outage data — is there a cleaner feed, or is scraping the only way?

0
赞同度 100% · 0 条评论 · 3 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。