Web Scraping Tabanlı Kentsel Haber İzleme ve Harita Üzerinde Görselleştirme Sistemi
Kocaeli Üniversitesi · Bilgisayar Mühendisliği · Yazılım Laboratuvarı-II · Proje I
Kocaeli'ye özel yerel haber sitelerinden haberleri otomatik olarak toplayan, sınıflandıran, konum bilgisi çıkaran ve Google Maps üzerinde görselleştiren full-stack bir web uygulamasıdır.
Şehir yaşamını etkileyen olaylar (trafik kazaları, yangınlar, elektrik kesintileri vb.) birçok farklı haber sitesinde dağınık şekilde yayımlanmaktadır. Bu proje, Kocaeli ili sınırları içindeki yerel haberleri tek bir merkezde toplayarak:
┌─────────────────────────────────────────────────────────┐
│ KULLANICI (Tarayıcı) │
│ React 19 + Vite + Google Maps │
└──────────────────────────┬──────────────────────────────┘
│ HTTP / REST API
┌──────────────────────────▼──────────────────────────────┐
│ ASP.NET Core 9 Web API │
│ ┌──────────┐ ┌───────────────┐ ┌────────────────────┐ │
│ │ Scrapers │ │ Classification│ │ Location & Geocode │ │
│ │ (RSS+HAP)│ │ Service │ │ Service │ │
│ └──────────┘ └───────────────┘ └────────────────────┘ │
│ ┌──────────────────┐ ┌────────────────────────────┐ │
│ │ Text Cleaning │ │ Similarity Service │ │
│ │ Service │ │ (SBERT veya TF-IDF) │ │
│ └──────────────────┘ └────────────────────────────┘ │
└──────────────────────────┬──────────────────────────────┘
│
┌──────────────────────────▼──────────────────────────────┐
│ MongoDB (NoSQL) │
│ KocaeliNewsDB (news + locationCache) │
└─────────────────────────────────────────────────────────┘
| Katman | Teknoloji | Açıklama |
|---|---|---|
| Backend | ASP.NET Core 9 | REST API, scraping orkestrasyon, iş mantığı |
| Frontend | React 19 + Vite 6 | SPA arayüz, harita görselleştirme |
| Veritabanı | MongoDB | Haber verilerinin NoSQL olarak saklanması |
| Harita | Google Maps JavaScript API | Haberlerin harita üzerinde gösterimi |
| Scraping | RSS + HtmlAgilityPack | RSS feed parse + HTML scrape |
| Geocoding | Google Geocoding API | Konum metni → enlem/boylam dönüşümü |
KocaeliNewsMonitor/
├── backend/
│ ├── KocaeliNews.sln # .NET Solution dosyası
│ └── KocaeliNews.API/
│ ├── Controllers/
│ │ ├── NewsController.cs # GET /api/news, GET /api/news/map
│ │ └── ScrapingController.cs # POST /api/scraping/start
│ ├── Models/
│ │ ├── News.cs # Haber modeli + NewsType enum + SourceInfo
│ │ ├── FilterRequest.cs # Filtre parametreleri (tür, ilçe, tarih)
│ │ └── ScrapingResult.cs # Pipeline analiz ve sonuç DTO'su
│ │
│ ├── Services/
│ │ ├── MongoDbService.cs # MongoDB bağlantı, CRUD, filtre sorguları
│ │ ├── ScrapingOrchestrator.cs # 5 siteyi paralel koordine eder
│ │ ├── TextCleaningService.cs # HTML temizleme, metin normalizasyon
│ │ ├── ClassificationService.cs # Ağırlıklı keyword sınıflandırma
│ │ ├── LocationService.cs # Haber metninden ilçe/mahalle çıkarımı
│ │ ├── GeocodingService.cs # Google Geocoding API + MongoDB cache
│ │ ├── SimilarityService.cs # SBERT veya TF-IDF + Cosine Similarity
│ │ └── Scrapers/
│ │ ├── INewsScraper.cs # Scraper arayüzü (interface)
│ │ ├── BaseScraper.cs # Rate limiting, RSS parse, retry (abstract)
│ │ ├── CagdasKocaeliScraper.cs # Daktilo CMS (sites/549)
│ │ ├── OzgurKocaeliScraper.cs # Daktilo CMS (sites/535)
│ │ ├── SesKocaeliScraper.cs # Daktilo CMS (sites/498)
│ │ ├── BizimYakaScraper.cs # Daktilo CMS (sites/358)
│ │ └── YeniKocaeliScraper.cs # Farklı CMS (her haber HTML scrape)
│ ├── appsettings.json # MongoDB + genel ayarlar
│ ├── appsettings.Development.json # 🔒 API key (gitignore)
│ ├── appsettings.Development.example.json # 📋 Şablon
│ └── Program.cs # DI, CORS, HttpClientFactory
│
├── frontend/
│ ├── index.html
│ ├── vite.config.js # API proxy ayarı (/api → localhost:5062)
│ ├── package.json
│ ├── .env.local # 🔒 Google Maps API Key (gitignore)
│ ├── .env.example # 📋 Şablon
│ └── src/
│ ├── main.jsx
│ ├── App.jsx
│ ├── App.css
│ ├── components/
│ │ ├── Header.jsx # Üst menü
│ │ ├── FilterPanel.jsx # Filtre arayüzü (tür, ilçe, tarih)
│ │ ├── MapView.jsx # Google Maps harita bileşeni
│ │ ├── NewsCard.jsx # Tek haber kartı
│ │ └── Sidebar.jsx # Haber listesi paneli
│ ├── services/
│ │ └── api.js # Axios ile backend API çağrıları
│ └── utils/
│ └── markerIcons.js # Kategori bazlı marker renkleri
│
├── .env.example # Ortam değişkenleri rehberi
├── .gitignore
└── README.md
| # | Kaynak | CMS | RSS tam metin | google-news.xml | Strateji |
|---|---|---|---|---|---|
| 1 | cagdaskocaeli.com.tr | Daktilo | ✅ | ✅ | RSS + google-news |
| 2 | ozgurkocaeli.com.tr | Daktilo | ✅ | ✅ | RSS + google-news |
| 3 | seskocaeli.com | Daktilo | ✅ | ✅ | RSS + google-news |
| 4 | bizimyaka.com | Daktilo | ✅ | ✅ | RSS + google-news |
| 5 | yenikocaeli.com | Farklı | ❌ | ✅ | RSS + google-news (HTML scrape) |
4 site aynı Daktilo CMS → aynı scraper mantığı. yenikocaeli farklı CMS → ayrı scraper.
| Aşama | Kaynak | Ne zaman | Maliyet |
|---|---|---|---|
| İlk yükleme | google-news.xml → URL → HTML scrape | 1 kez (ilk açılış) | ~80 istek/site, ~2.5 dk |
| Sürekli izleme | RSS feed (content:encoded) | Her 15 dakika | 1 istek/site, <1 sn |
İlk Yükleme (3 günlük geçmiş):
4 Daktilo site → google-news.xml → URL listesi → detay sayfası scrape → tam metin
yenikocaeli → google-news.xml → URL listesi → detay sayfası scrape → tam metin
Sürekli İzleme (her 15 dakika):
4 Daktilo site → RSS → content:encoded (tam metin var, scrape'e gerek yok ⚡)
yenikocaeli → RSS → URL → detay sayfası scrape → tam metin
Task.WhenAll) → toplam süre = en yavaş siteSemaphoreSlim(1,1)) → aynı anda max 1 istekKocaeliHaberBot/1.0 → şeffaf kimlikHer haber otomatik olarak tek bir kategoriye sınıflandırılır:
| Renk | Tür | Açıklama |
|---|---|---|
| 🔴 | Trafik Kazası | Araç kazaları, trafik olayları |
| 🟠 | Yangın | Yangın haberleri, itfaiye müdahaleleri |
| 🟡 | Elektrik Kesintisi | Planlı/plansız elektrik kesintileri |
| 🟣 | Hırsızlık | Hırsızlık, dolandırıcılık olayları |
| 🟢 | Kültürel Etkinlik | Festival, konser, sergi, tören |
Sınıflandırma yöntemi: Ağırlıklı keyword matching (bigram/trigram + exclusion kuralları). Güçlü keyword (10p) + destek keyword (5p) + exclusion → false positive önleme.
SemaphoreSlim, rastgele gecikme) ile ban korumasıemrecan/bert-base-turkish-cased-mean-nli-stsb-tr — semantik anlam, ONNX Runtime| Araç | Minimum Versiyon |
|---|---|
| .NET SDK | 9.0 |
| Node.js | 18+ |
| MongoDB | 7.0+ (servis olarak kur) |
| Google API Key | Maps JavaScript + Geocoding API |
cd backend
dotnet restore
cd KocaeliNews.API
cp appsettings.Development.example.json appsettings.Development.json
# appsettings.Development.json → GeocodingApiKey'i kendi key'inle değiştir
appsettings.json→ MongoDB + genel ayarlar (değiştirme).appsettings.Development.json→ sadece API key (gitignore'da). .NET bu ikisini otomatik birleştirir.
cd frontend
npm install
echo VITE_GOOGLE_MAPS_API_KEY=SENIN_MAPS_API_KEYIN > .env.local
# MongoDB çalışıyor mu?
Get-Service MongoDB # Status: Running olmalı
# Terminal 1: Backend
cd backend && dotnet run --project KocaeliNews.API
# → http://localhost:5062
# Terminal 2: Frontend
cd frontend && npm run dev
# → http://localhost:5173
| Metod | Endpoint | Açıklama |
|---|---|---|
GET | /api/news | Tüm haberleri listele (varsayılan: son 3 gün) |
GET | /api/news?newsType=Fire&district=Gebze | Filtrelenmiş haberler |
GET | /api/news/map | Sadece koordinatlı haberler (harita için) |
POST | /api/scraping/start | Scraping işlemini başlat (ScrapingResult nesnesi döner) |
GET | /api/scraping/test-scraper?source={name} | Sadece belirtilen siteden veri çeker, DB'ye yazmaz |
GET | /api/scraping/test-pipeline?source={name} | Belirtilen siteden veri çeker ve sınıflandırır, DB'ye yazmaz |
GET | /api/scraping/sources | Sistemde kayıtlı olan aktif scraper'ları listeler |
Kocaeli Üniversitesi · Bilgisayar Mühendisliği · 2025-2026
C#
77.7%
JavaScript
12.7%
CSS
9.4%
Web Scraping Tabanlı Kentsel Haber İzleme ve Harita Üzerinde Görselleştirme Sistemi
Kocaeli Üniversitesi · Bilgisayar Mühendisliği · Yazılım Laboratuvarı-II · Proje I
Kocaeli'ye özel yerel haber sitelerinden haberleri otomatik olarak toplayan, sınıflandıran, konum bilgisi çıkaran ve Google Maps üzerinde görselleştiren full-stack bir web uygulamasıdır.
Şehir yaşamını etkileyen olaylar (trafik kazaları, yangınlar, elektrik kesintileri vb.) birçok farklı haber sitesinde dağınık şekilde yayımlanmaktadır. Bu proje, Kocaeli ili sınırları içindeki yerel haberleri tek bir merkezde toplayarak:
┌─────────────────────────────────────────────────────────┐
│ KULLANICI (Tarayıcı) │
│ React 19 + Vite + Google Maps │
└──────────────────────────┬──────────────────────────────┘
│ HTTP / REST API
┌──────────────────────────▼──────────────────────────────┐
│ ASP.NET Core 9 Web API │
│ ┌──────────┐ ┌───────────────┐ ┌────────────────────┐ │
│ │ Scrapers │ │ Classification│ │ Location & Geocode │ │
│ │ (RSS+HAP)│ │ Service │ │ Service │ │
│ └──────────┘ └───────────────┘ └────────────────────┘ │
│ ┌──────────────────┐ ┌────────────────────────────┐ │
│ │ Text Cleaning │ │ Similarity Service │ │
│ │ Service │ │ (SBERT veya TF-IDF) │ │
│ └──────────────────┘ └────────────────────────────┘ │
└──────────────────────────┬──────────────────────────────┘
│
┌──────────────────────────▼──────────────────────────────┐
│ MongoDB (NoSQL) │
│ KocaeliNewsDB (news + locationCache) │
└─────────────────────────────────────────────────────────┘
| Katman | Teknoloji | Açıklama |
|---|---|---|
| Backend | ASP.NET Core 9 | REST API, scraping orkestrasyon, iş mantığı |
| Frontend | React 19 + Vite 6 | SPA arayüz, harita görselleştirme |
| Veritabanı | MongoDB | Haber verilerinin NoSQL olarak saklanması |
| Harita | Google Maps JavaScript API | Haberlerin harita üzerinde gösterimi |
| Scraping | RSS + HtmlAgilityPack | RSS feed parse + HTML scrape |
| Geocoding | Google Geocoding API | Konum metni → enlem/boylam dönüşümü |
KocaeliNewsMonitor/
├── backend/
│ ├── KocaeliNews.sln # .NET Solution dosyası
│ └── KocaeliNews.API/
│ ├── Controllers/
│ │ ├── NewsController.cs # GET /api/news, GET /api/news/map
│ │ └── ScrapingController.cs # POST /api/scraping/start
│ ├── Models/
│ │ ├── News.cs # Haber modeli + NewsType enum + SourceInfo
│ │ ├── FilterRequest.cs # Filtre parametreleri (tür, ilçe, tarih)
│ │ └── ScrapingResult.cs # Pipeline analiz ve sonuç DTO'su
│ │
│ ├── Services/
│ │ ├── MongoDbService.cs # MongoDB bağlantı, CRUD, filtre sorguları
│ │ ├── ScrapingOrchestrator.cs # 5 siteyi paralel koordine eder
│ │ ├── TextCleaningService.cs # HTML temizleme, metin normalizasyon
│ │ ├── ClassificationService.cs # Ağırlıklı keyword sınıflandırma
│ │ ├── LocationService.cs # Haber metninden ilçe/mahalle çıkarımı
│ │ ├── GeocodingService.cs # Google Geocoding API + MongoDB cache
│ │ ├── SimilarityService.cs # SBERT veya TF-IDF + Cosine Similarity
│ │ └── Scrapers/
│ │ ├── INewsScraper.cs # Scraper arayüzü (interface)
│ │ ├── BaseScraper.cs # Rate limiting, RSS parse, retry (abstract)
│ │ ├── CagdasKocaeliScraper.cs # Daktilo CMS (sites/549)
│ │ ├── OzgurKocaeliScraper.cs # Daktilo CMS (sites/535)
│ │ ├── SesKocaeliScraper.cs # Daktilo CMS (sites/498)
│ │ ├── BizimYakaScraper.cs # Daktilo CMS (sites/358)
│ │ └── YeniKocaeliScraper.cs # Farklı CMS (her haber HTML scrape)
│ ├── appsettings.json # MongoDB + genel ayarlar
│ ├── appsettings.Development.json # 🔒 API key (gitignore)
│ ├── appsettings.Development.example.json # 📋 Şablon
│ └── Program.cs # DI, CORS, HttpClientFactory
│
├── frontend/
│ ├── index.html
│ ├── vite.config.js # API proxy ayarı (/api → localhost:5062)
│ ├── package.json
│ ├── .env.local # 🔒 Google Maps API Key (gitignore)
│ ├── .env.example # 📋 Şablon
│ └── src/
│ ├── main.jsx
│ ├── App.jsx
│ ├── App.css
│ ├── components/
│ │ ├── Header.jsx # Üst menü
│ │ ├── FilterPanel.jsx # Filtre arayüzü (tür, ilçe, tarih)
│ │ ├── MapView.jsx # Google Maps harita bileşeni
│ │ ├── NewsCard.jsx # Tek haber kartı
│ │ └── Sidebar.jsx # Haber listesi paneli
│ ├── services/
│ │ └── api.js # Axios ile backend API çağrıları
│ └── utils/
│ └── markerIcons.js # Kategori bazlı marker renkleri
│
├── .env.example # Ortam değişkenleri rehberi
├── .gitignore
└── README.md
| # | Kaynak | CMS | RSS tam metin | google-news.xml | Strateji |
|---|---|---|---|---|---|
| 1 | cagdaskocaeli.com.tr | Daktilo | ✅ | ✅ | RSS + google-news |
| 2 | ozgurkocaeli.com.tr | Daktilo | ✅ | ✅ | RSS + google-news |
| 3 | seskocaeli.com | Daktilo | ✅ | ✅ | RSS + google-news |
| 4 | bizimyaka.com | Daktilo | ✅ | ✅ | RSS + google-news |
| 5 | yenikocaeli.com | Farklı | ❌ | ✅ | RSS + google-news (HTML scrape) |
4 site aynı Daktilo CMS → aynı scraper mantığı. yenikocaeli farklı CMS → ayrı scraper.
| Aşama | Kaynak | Ne zaman | Maliyet |
|---|---|---|---|
| İlk yükleme | google-news.xml → URL → HTML scrape | 1 kez (ilk açılış) | ~80 istek/site, ~2.5 dk |
| Sürekli izleme | RSS feed (content:encoded) | Her 15 dakika | 1 istek/site, <1 sn |
İlk Yükleme (3 günlük geçmiş):
4 Daktilo site → google-news.xml → URL listesi → detay sayfası scrape → tam metin
yenikocaeli → google-news.xml → URL listesi → detay sayfası scrape → tam metin
Sürekli İzleme (her 15 dakika):
4 Daktilo site → RSS → content:encoded (tam metin var, scrape'e gerek yok ⚡)
yenikocaeli → RSS → URL → detay sayfası scrape → tam metin
Task.WhenAll) → toplam süre = en yavaş siteSemaphoreSlim(1,1)) → aynı anda max 1 istekKocaeliHaberBot/1.0 → şeffaf kimlikHer haber otomatik olarak tek bir kategoriye sınıflandırılır:
| Renk | Tür | Açıklama |
|---|---|---|
| 🔴 | Trafik Kazası | Araç kazaları, trafik olayları |
| 🟠 | Yangın | Yangın haberleri, itfaiye müdahaleleri |
| 🟡 | Elektrik Kesintisi | Planlı/plansız elektrik kesintileri |
| 🟣 | Hırsızlık | Hırsızlık, dolandırıcılık olayları |
| 🟢 | Kültürel Etkinlik | Festival, konser, sergi, tören |
Sınıflandırma yöntemi: Ağırlıklı keyword matching (bigram/trigram + exclusion kuralları). Güçlü keyword (10p) + destek keyword (5p) + exclusion → false positive önleme.
SemaphoreSlim, rastgele gecikme) ile ban korumasıemrecan/bert-base-turkish-cased-mean-nli-stsb-tr — semantik anlam, ONNX Runtime| Araç | Minimum Versiyon |
|---|---|
| .NET SDK | 9.0 |
| Node.js | 18+ |
| MongoDB | 7.0+ (servis olarak kur) |
| Google API Key | Maps JavaScript + Geocoding API |
cd backend
dotnet restore
cd KocaeliNews.API
cp appsettings.Development.example.json appsettings.Development.json
# appsettings.Development.json → GeocodingApiKey'i kendi key'inle değiştir
appsettings.json→ MongoDB + genel ayarlar (değiştirme).appsettings.Development.json→ sadece API key (gitignore'da). .NET bu ikisini otomatik birleştirir.
cd frontend
npm install
echo VITE_GOOGLE_MAPS_API_KEY=SENIN_MAPS_API_KEYIN > .env.local
# MongoDB çalışıyor mu?
Get-Service MongoDB # Status: Running olmalı
# Terminal 1: Backend
cd backend && dotnet run --project KocaeliNews.API
# → http://localhost:5062
# Terminal 2: Frontend
cd frontend && npm run dev
# → http://localhost:5173
| Metod | Endpoint | Açıklama |
|---|---|---|
GET | /api/news | Tüm haberleri listele (varsayılan: son 3 gün) |
GET | /api/news?newsType=Fire&district=Gebze | Filtrelenmiş haberler |
GET | /api/news/map | Sadece koordinatlı haberler (harita için) |
POST | /api/scraping/start | Scraping işlemini başlat (ScrapingResult nesnesi döner) |
GET | /api/scraping/test-scraper?source={name} | Sadece belirtilen siteden veri çeker, DB'ye yazmaz |
GET | /api/scraping/test-pipeline?source={name} | Belirtilen siteden veri çeker ve sınıflandırır, DB'ye yazmaz |
GET | /api/scraping/sources | Sistemde kayıtlı olan aktif scraper'ları listeler |
Kocaeli Üniversitesi · Bilgisayar Mühendisliği · 2025-2026
C#
77.7%
JavaScript
12.7%
CSS
9.4%