Bu proje, SofaScore'dan futbol maçlarının verilerini çekmek, analiz etmek ve yönetmek için geliştirilmiş bir Python uygulamasıdır. Farklı ligler, sezonlar ve maçlar hakkında kapsamlı veri toplama, işleme ve dışa aktarma imkanı sunar.
- Özellikler
- Sistem Gereksinimleri
- Kurulum
- Kullanım
- Konfigürasyon
- Veri Yapısı
- Çıktılar ve Veri Formatları
- Nasıl Yapılır (How-to)
- Sık Sorulan Sorular (SSS)
- Mimari ve Geliştirme
- Sorun Giderme
- Katkıda Bulunma
- Lisans
SofaScore Scraper, aşağıdaki temel özellikleri sunar:
-
Lig Yönetimi:
- Ligleri listeleme, ekleme ve kaldırma
- Desteklenen tüm SofaScore liglerini görüntüleme
-
Sezon İşlemleri:
- Liglere ait tüm sezonları çekme ve listeleme
- Aktif sezonları otomatik tespit etme
- Geçmiş ve gelecek sezonları yönetme
-
Maç Verileri:
- Belirli bir lig ve sezon için maç listelerini çekme
- Haftalık/turlu maç verilerini görüntüleme
- Tüm ligler için toplu maç verisi toplama
-
Maç Detayları:
- Maç istatistiklerini çekme
- Takım serilerini görüntüleme
- Maç öncesi form verilerini toplama
- Karşılıklı istatistikleri (H2H) inceleme
-
Veri Dışa Aktarma:
- Maç verilerini CSV formatına dönüştürme
- Lig bazlı veya tüm liglerin verilerini tek seferde dışa aktarma
- Tek bir maçın detaylarını CSV formatında kaydetme
-
Kullanıcı Arayüzü:
- Sezgisel terminal tabanlı menü sistemi
- Renkli ve kategorize edilmiş çıktılar
- İlerleme çubukları ve işlem durum göstergeleri
- Detaylı hata mesajları ve loglama
- Python 3.8 veya üzeri
- pip (Python paket yöneticisi)
- İnternet bağlantısı (SofaScore API'ye erişmek için)
- 100 MB+ disk alanı (toplanan verilerin miktarına bağlı olarak değişir)
GitHub deposundan projeyi klonlayın:
git clone https://github.com/tunjayoff/sofascore_scraper.git
cd sofascore_scraperAlternatif olarak, projeyi ZIP olarak indirip açabilirsiniz.
Python sanal ortamı oluşturmak, paket çakışmalarını önlemeye yardımcı olur:
# Sanal ortam oluşturma
python -m venv venv
# Sanal ortamı aktifleştirme
# Linux/MacOS için:
source venv/bin/activate
# Windows için:
venv\Scripts\activateGerekli Python paketlerini yükleyin:
pip install -r requirements.txt.env dosyasını kullanarak çevre değişkenlerini yapılandırabilirsiniz:
# .env.example dosyasını kopyalayın
cp .env.example .env
# Düzenleyin
nano .env # veya tercih ettiğiniz metin editörüUygulamayı çalıştırmak için ana dizinde şu komutu kullanın:
python main.pyBelirli parametrelerle çalıştırmak için:
# Arayüz olmadan çalıştırma (headless mode)
python main.py --headless
# Tüm liglerin verilerini güncelleme
python main.py --headless --update-all
# Verileri CSV formatında dışa aktarma
python main.py --headless --csv-exportUygulama başladığında karşınıza bir ana menü gelecektir:
SofaScore Scraper v1.0.0
==========================================
Ana Menü:
--------------------------------------------------
1. 🏆 Lig İşlemleri
2. 🗓️ Sezon İşlemleri
3. ⚽ Maç İşlemleri
4. 📊 Maç Detayları
5. ⚙️ Ayarlar
0. 🚪 Çıkış
Seçiminiz (0-5):
- Ligleri Listele: Kayıtlı ligleri görüntüler
- Lig Ekle: Yeni bir lig ekler (Lig adı ve ID'si gereklidir)
- Lig Sil: Mevcut bir ligi kaldırır
- Lig Ara: Ligleri ada göre arar
- Ana Menüye Dön: Ana menüye geri döner
- Sezonları Listele: Kayıtlı sezonları görüntüler
- Sezon Verilerini Çek: Belirli bir lig için sezon verilerini çeker
- Tüm Ligler İçin Sezon Verilerini Çek: Tüm ligler için sezon verilerini çeker
- Ana Menüye Dön: Ana menüye geri döner
- Maçları Listele: Çekilen maçları listeler
- Maç Verilerini Çek: Belirli bir lig ve sezon için maç verilerini çeker
- Tüm Ligler İçin Maç Verilerini Çek: Tüm ligler için maç verilerini çeker
- Ana Menüye Dön: Ana menüye geri döner
- Maç Detaylarını Çek: Belirli maçlar için detaylı verileri çeker
- Tüm Maçlar İçin Detayları Çek: Tüm maçlar için detaylı verileri çeker
- CSV Veri Seti Oluştur: Maç verilerini CSV formatına dönüştürür
- Ana Menüye Dön: Ana menüye geri döner
SofaScore Scraper, iki farklı yöntemle yapılandırılabilir:
Proje, .env dosyası aracılığıyla çevre değişkenleri kullanarak konfigüre edilebilir. Örnek bir .env dosyası:
# Sofascore Scraper yapılandırma değişkenleri
API_BASE_URL='https://www.sofascore.com/api/v1'
REQUEST_TIMEOUT='20'
MAX_RETRIES='3'
MAX_CONCURRENT='25'
WAIT_TIME_MIN=0.4
WAIT_TIME_MAX=0.8
DATA_DIR='data'
FETCH_ONLY_FINISHED=true
SAVE_EMPTY_ROUNDS=false
USE_COLOR=true
DATE_FORMAT="%Y-%m-%d %H:%M:%S"
USE_PROXY=false
PROXY_URL=''
Lig bilgilerini config/leagues.txt dosyasında yönetebilirsiniz:
# Format: Lig Adı: ID
Premier League: 17
LaLiga: 8
Serie A: 23
Bundesliga: 35
Ligue 1: 34
Süper Lig: 52
SofaScore Scraper, topladığı verileri aşağıdaki yapıda organize eder:
data/
├── seasons/
│ └── {lig_id}_{lig_adı}_seasons.json
├── matches/
│ └── {lig_id}_{lig_adı}/
│ └── {sezon_id}_{sezon_adı}/
│ ├── round_1.json
│ ├── round_2.json
│ └── ...
└── match_details/
└── {lig_adı}/
└── season_{sezon_adı}/
└── {maç_id}/
├── full_data.json
├── basic.json
├── statistics.json
├── team_streaks.json
├── pregame_form.json
└── h2h.json
- seasons.json: Bir lig için tüm sezonların listesi
- round_X.json: Bir sezonun belirli bir turu/haftası için maçlar
- full_data.json: Bir maç için toplanan tüm veriler
- basic.json: Maçın temel bilgileri (takımlar, skor, tarih, vb.)
- statistics.json: Maç istatistikleri (şutlar, paslar, korneler, vb.)
- team_streaks.json: Takımların seriler/istatistikleri
- pregame_form.json: Maç öncesi takım formları
- h2h.json: Takımlar arası karşılaşma geçmişi
CSV dosyaları data/match_details/processed/ dizinine kaydedilir:
- Tek Maç CSV:
{maç_id}_{timestamp}.csv - Lig Maçları CSV:
{lig_adı}_{timestamp}.csv - Tüm Maçlar CSV:
all_matches_{timestamp}.csv
Örnek CSV çıktısı:
match_id,tournament_name,season_name,round,home_team_name,away_team_name,home_score_ft,away_score_ft,match_date,home_possession,away_possession,home_shots_total,away_shots_total,home_shots_on_target,away_shots_on_target
10257123,Premier League,2023/2024,38,Manchester City,West Ham,3,1,1621789200,65,35,23,5,12,2JSON dosyaları, SofaScore API'nin döndürdüğü veri yapısını korur, ancak bazı durumlarda ek bilgilerle zenginleştirilir.
Örnek bir basic.json dosyası:
{
"tournament": {
"name": "Premier League",
"slug": "premier-league",
"category": {
"name": "England",
"slug": "england",
"sport": {
"name": "Football",
"slug": "football",
"id": 1
},
"id": 1,
"flag": "england"
},
"uniqueTournament": {
"name": "Premier League",
"slug": "premier-league",
"category": {
"name": "England",
"slug": "england",
"sport": {
"name": "Football",
"slug": "football",
"id": 1
},
"id": 1,
"flag": "england"
},
"userCount": 1327093,
"hasEventPlayerStatistics": true,
"crowdsourcingEnabled": false,
"hasPerformanceGraphFeature": true,
"id": 17,
"hasPositionGraph": true
},
"primaryColorHex": "#3c1c5a",
"secondaryColorHex": "#000000",
"id": 29415
}
}Yeni bir lig eklemek için iki yöntem vardır:
Ana menüden "Lig İşlemleri" seçip "Lig Ekle" seçeneğini kullanabilirsiniz.
config/leagues.txtdosyasını bir metin editöründe açın- Yeni ligi şu formatla ekleyin:
Lig Adı: ID
Premier League: 17
LaLiga: 8
Serie A: 23
Bundesliga: 35
Ligue 1: 34
Süper Lig: 52
Brasileirão Betano: 325
Belirli bir lig ve sezon için tüm maçları çekmek için:
- Ana menüden "Maç İşlemleri"ni seçin (3)
- "Maç Verilerini Çek" seçeneğini seçin (2)
- Ligler listesinden hedef ligi seçin
- Sezon filtreleme seçeneğinden "Belirli Bir Sezon" seçin (3)
- Sezon listesinden istediğiniz sezonu seçin
Python kodunda programatik olarak kullanım:
from src.config_manager import ConfigManager
from src.match_fetcher import MatchFetcher
from src.season_fetcher import SeasonFetcher
# Config yöneticisini başlat
config = ConfigManager()
# Sezon ve maç çekicilerini başlat
season_fetcher = SeasonFetcher(config)
match_fetcher = MatchFetcher(config, season_fetcher)
# Süper Lig (ID: 52) için aktif sezonu al
season_id = season_fetcher.get_current_season_id(52)
# Süper Lig'in aktif sezonu için tüm maçları çek
success = match_fetcher.fetch_matches_for_season(52, season_id)
if success:
print("Tüm maçlar başarıyla çekildi!")
else:
print("Maç çekme işlemi başarısız!")Çekilen maç verilerini CSV formatına dönüştürmek için:
- Ana menüden "Maç Detayları"nı seçin (4)
- "CSV Veri Seti Oluştur" seçeneğini seçin (3)
- Dönüştürme seçeneklerinden birini seçin:
- Tek Maç CSV
- Belirli Bir Lig İçin CSV
- Tüm Ligler İçin CSV
Belirli bir lig için CSV veri seti oluşturma örneği:
from src.config_manager import ConfigManager
from src.match_data_fetcher import MatchDataFetcher
# Config yöneticisini başlat
config = ConfigManager()
# Maç veri çekicisini başlat
match_data_fetcher = MatchDataFetcher(config)
# Süper Lig (ID: 52) için CSV veri seti oluştur
csv_paths = match_data_fetcher.convert_league_matches_to_csv("52")
if csv_paths:
print(f"CSV dosyaları oluşturuldu: {csv_paths}")
else:
print("CSV oluşturma işlemi başarısız!")Belirli bir maçın detaylarını çekmek ve analiz etmek için:
- Ana menüden "Maç Detayları"nı seçin (4)
- "Maç Detaylarını Çek" seçeneğini seçin (1)
- Maç ID'sini girin (Maç ID'lerini "Maçları Listele" seçeneğinden bulabilirsiniz)
Örnek: Bir maçın istatistiklerini Python'da analiz etme:
import json
import os
from src.config_manager import ConfigManager
from src.match_data_fetcher import MatchDataFetcher
# Config yöneticisini başlat
config = ConfigManager()
# Maç veri çekicisini başlat
match_data_fetcher = MatchDataFetcher(config)
# Maç ID'si
match_id = "10257123" # Örnek bir maç ID'si
# Maç detaylarını çek
success = match_data_fetcher.fetch_match_details(match_id)
if success:
# Maç dizinini bul
match_path = match_data_fetcher._find_match_path(match_id)
if match_path:
league_dir, season_dir, match_dir = match_path
# İstatistikleri oku
stats_file = os.path.join(match_dir, "statistics.json")
with open(stats_file, 'r', encoding='utf-8') as f:
stats = json.load(f)
# İstatistikleri analiz et
print(f"Maç ID: {match_id}")
# Temel istatistikleri çıkar
for period in stats.get("statistics", []):
if period.get("period") == "ALL":
print("\nMaç İstatistikleri:")
for group in period.get("groups", []):
print(f"\n{group.get('groupName')}:")
for item in group.get("statisticsItems", []):
print(f" - {item.get('name')}: Ev {item.get('homeValue')} - Deplasman {item.get('awayValue')}")Verileri Python analiz araçlarıyla (Pandas, NumPy, vb.) kullanmak için:
import pandas as pd
import os
from src.config_manager import ConfigManager
from src.match_data_fetcher import MatchDataFetcher
# Config yöneticisini başlat
config = ConfigManager()
# Maç veri çekicisini başlat
match_data_fetcher = MatchDataFetcher(config)
# Süper Lig (ID: 52) için CSV dosyasını oluştur
csv_paths = match_data_fetcher.convert_league_matches_to_csv("52")
if csv_paths and csv_paths[0]:
# İlk CSV dosyasını Pandas DataFrame'e yükle
df = pd.read_csv(csv_paths[0])
# Veri analizi
print(f"Toplam maç sayısı: {len(df)}")
print(f"Ev sahibi gol ortalaması: {df['home_score_ft'].mean():.2f}")
print(f"Deplasman gol ortalaması: {df['away_score_ft'].mean():.2f}")
# En çok gol atan takımlar
home_goals = df.groupby('home_team_name')['home_score_ft'].sum()
away_goals = df.groupby('away_team_name')['away_score_ft'].sum()
# Toplam goller
team_goals = pd.DataFrame({
'Ev Golleri': home_goals,
'Deplasman Golleri': away_goals
}).fillna(0)
team_goals['Toplam Goller'] = team_goals['Ev Golleri'] + team_goals['Deplasman Golleri']
print("\nEn çok gol atan 5 takım:")
print(team_goals.sort_values('Toplam Goller', ascending=False).head(5))SofaScore web sitesinde, ligin URL'sine bakabilirsiniz. Örneğin, Süper Lig için URL https://www.sofascore.com/tournament/football/turkey/super-lig/52 şeklindedir. Buradaki son sayı (52) lig ID'sidir.
Maç ID'lerini birkaç yöntemle bulabilirsiniz:
- Uygulamada "Maçları Listele" seçeneğini kullanarak
- Çektiğiniz maç verilerini içeren JSON dosyalarından
SofaScore API, kısa sürede çok fazla istek yapıldığında rate-limiting uygulayabilir. Bu durumda şunları deneyebilirsiniz:
.envdosyasındaMAX_CONCURRENTdeğerini düşürün (örneğin 10'a)WAIT_TIME_MINveWAIT_TIME_MAXdeğerlerini artırın- Daha az veri çekerek başlayın ve zamanla artırın
Tüm veriler varsayılan olarak data/ dizini altında saklanır (.env dosyasında DATA_DIR değişkeni ile değiştirilebilir):
- Sezon verileri:
data/seasons/ - Maç listeleri:
data/matches/ - Maç detayları:
data/match_details/ - CSV çıktıları:
data/match_details/processed/
Şu anda uygulama Türkçe olarak geliştirilmiştir. Farklı diller için destek eklemeyi planlıyoruz.
SofaScore Scraper, modüler bir mimari kullanılarak geliştirilmiştir:
- ConfigManager: Konfigürasyon yönetimi ve çevre değişkenleri
- SeasonFetcher: Sezon verilerini çekme ve yönetme
- MatchFetcher: Maç listelerini çekme ve yönetme
- MatchDataFetcher: Detaylı maç verilerini çekme ve işleme
- SofaScoreUI: Ana kullanıcı arayüzü
- UI Modülleri: Farklı işlemler için özel UI sınıfları
ConfigManager → SeasonFetcher → MatchFetcher → MatchDataFetcher → CSV/JSON Çıktılar
SofaScore API'si resmi olarak belgelenmemiştir. Bu proje, web sitesinin ve mobil uygulamanın kullandığı aynı API'leri kullanır:
https://www.sofascore.com/api/v1/...
Maç detayları çekilirken, işlem hızını artırmak için asenkron HTTP istekleri kullanılır. Bu, aiohttp kütüphanesi ile gerçekleştirilir ve .env dosyasındaki MAX_CONCURRENT değişkeni ile kontrol edilebilir.
Kodu genişletmek veya değiştirmek isteyenler için:
- Yeni bir veri türü eklemek için
MatchDataFetchersınıfını genişletin - Yeni bir UI modülü için
src/ui/altında yeni bir sınıf oluşturun - API davranışı değişirse
utils.pyiçindekimake_api_requestfonksiyonunu güncelleyin
- API Hataları: SofaScore API'de değişiklikler olabileceğinden, güncellemeler gerekebilir.
- Rate Limiting: Çok fazla istek gönderildiğinde API istek sınırlamalarına takılabilirsiniz.
- Veri Boşlukları: Bazı maçlarda veya liglerde eksik veriler olabilir.
Hata mesajları logs/ dizininde kaydedilir. Sorun yaşadığınızda logları kontrol edin. Log seviyesi .env dosyasındaki LOG_LEVEL değişkeni ile kontrol edilebilir.
- Güncel Sürüm Kontrolü: Projenin en son sürümünü kullandığınızdan emin olun
- Bağımlılık Kontrolü:
requirements.txtdosyasındaki tüm paketlerin doğru sürümlerle yüklendiğini kontrol edin - Çevre Değişkenleri Kontrolü:
.envdosyasının doğru yapılandırıldığından emin olun - Log İncelemesi: Hata mesajları için
logs/dizinindeki dosyaları inceleyin - Ağ Kontrolü: SofaScore API'ye erişim sağlanabiliyor mu kontrol edin
Projeye katkıda bulunmak için:
- Bu depoyu "fork"layın
- Yeni bir dal oluşturun (
git checkout -b özellik/yenilik) - Değişikliklerinizi commit edin (
git commit -m 'Yeni özellik eklendi') - Dalınızı push edin (
git push origin özellik/yenilik) - Bir "Pull Request" açın
Bu proje MIT lisansı altında lisanslanmıştır. Detaylar için LICENSE dosyasına bakın.
Geliştirici: Tuncay Eşsiz
Sürüm: 1.0.0
Son güncelleme: Mart 2024