- Add get_club_results.py: Extract all results for a club from results CSV - Fuzzy search for club names - List clubs functionality - Export results to CSV - Add scrape_course_details.py: Scrape detailed info from course pages - Extract competition ID (frmcompetition) - Extract event details (distance, category, sex) - Extract course website link - Extract location and organizer info - Update README.md with new scripts and usage examples - Update version to v1.3.0
556 lines
18 KiB
Markdown
556 lines
18 KiB
Markdown
# FFA Calendar Scraper
|
|
|
|
Un système complet pour scraper les données du site de la Fédération Française d'Athlétisme (FFA) et les organiser dans des fichiers CSV avec des fonctionnalités de recherche et d'analyse.
|
|
|
|
## 📋 Table des matières
|
|
|
|
- [Fonctionnalités](#fonctionnalités)
|
|
- [Structure du projet](#structure-du-projet)
|
|
- [Installation](#installation)
|
|
- [Configuration](#configuration)
|
|
- [Utilisation](#utilisation)
|
|
- [Structure des données](#structure-des-données)
|
|
- [Scripts disponibles](#scripts-disponibles)
|
|
- [Version](#version)
|
|
- [Contribuer](#contribuer)
|
|
- [Licence](#licence)
|
|
|
|
## ✨ Fonctionnalités
|
|
|
|
### Scraping des données
|
|
- **Calendrier des compétitions**: Récupération automatique du calendrier complet (2010-2026)
|
|
- **Détails des courses**: Extraction des informations détaillées de chaque compétition
|
|
- **Résultats des compétitions**: Récupération des résultats par athlète (place, temps, club)
|
|
- **Multithreading**: Scraping optimisé avec plusieurs workers pour accélérer le processus
|
|
- **Pagination automatique**: Détection automatique du nombre de pages et de courses
|
|
|
|
### Analyse des données
|
|
- **Recherche d'athlètes**: Par nom/prénom dans toutes les compétitions
|
|
- **Recherche de clubs**: Identification des athlètes par club
|
|
- **Recherche de courses**: Par période de dates
|
|
- **Statistiques détaillées**: Performances par athlète, podiums, etc.
|
|
- **Classements**: Classements par club pour chaque course
|
|
|
|
### Export et traitement
|
|
- **Export CSV**: Format compatible Excel, encodage UTF-8
|
|
- **Export personnalisé**: Export des résultats par athlète
|
|
- **Post-traitement**: Scripts pour analyser et transformer les données
|
|
|
|
## 📁 Structure du projet
|
|
|
|
```
|
|
ffa-calendar/
|
|
├── src/ # Modules Python principaux
|
|
│ ├── ffa_scraper.py # Scraper principal
|
|
│ └── ffa_analyzer.py # Analyseur de données
|
|
├── scripts/ # Scripts autonomes
|
|
│ ├── ffa_cli.py # Interface CLI principale
|
|
│ ├── search_athlete.py # Recherche d'athlètes
|
|
│ ├── search_race.py # Recherche de courses
|
|
│ ├── extract_races.py # Extraction des courses
|
|
│ ├── list_clubs.py # Liste des clubs
|
|
│ ├── post_process.py # Post-traitement des données
|
|
│ ├── monitor_scraping.py # Surveillance du scraping
|
|
│ ├── scrape_all_periods.py # Scraping par périodes
|
|
│ ├── athlete_summary.py # Résumé par athlète
|
|
│ ├── get_club_results.py # Extraction des résultats par club
|
|
│ └── scrape_course_details.py # Scraping des détails des courses
|
|
├── config/ # Fichiers de configuration
|
|
│ └── config.env # Configuration du scraper
|
|
├── data/ # Données générées
|
|
│ ├── courses/ # Données des courses
|
|
│ │ └── periods/ # Courses par périodes
|
|
│ ├── resultats/ # Résultats des compétitions
|
|
│ ├── clubs/ # Données des clubs
|
|
│ └── exports/ # Exports personnalisés
|
|
├── docs/ # Documentation
|
|
├── tests/ # Tests unitaires
|
|
├── requirements.txt # Dépendances Python
|
|
├── README.md # Ce fichier
|
|
├── LICENSE # Licence MIT
|
|
└── .gitignore # Fichiers ignorés par Git
|
|
```
|
|
|
|
## 🚀 Installation
|
|
|
|
### Prérequis
|
|
|
|
- Python 3.8 ou supérieur
|
|
- Google Chrome (pour Selenium)
|
|
- pip (gestionnaire de paquets Python)
|
|
|
|
### Étapes d'installation
|
|
|
|
1. **Cloner le dépôt**
|
|
```bash
|
|
git clone https://github.com/votre-username/ffa-calendar.git
|
|
cd ffa-calendar
|
|
```
|
|
|
|
2. **Créer un environnement virtuel (recommandé)**
|
|
```bash
|
|
python -m venv venv
|
|
source venv/bin/activate # Linux/Mac
|
|
# ou
|
|
venv\Scripts\activate # Windows
|
|
```
|
|
|
|
3. **Installer les dépendances**
|
|
```bash
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
4. **Configurer le scraper**
|
|
```bash
|
|
cp config/config.env config/config.local.env
|
|
# Éditez config/config.local.env selon vos besoins
|
|
```
|
|
|
|
## ⚙️ Configuration
|
|
|
|
Le scraper se configure via le fichier `config/config.env`. Les principaux paramètres sont:
|
|
|
|
### Répertoires
|
|
- `OUTPUT_DIR`: Répertoire de sortie des données (défaut: `data`)
|
|
- `EXPORT_DIR`: Répertoire pour les exports personnalisés
|
|
|
|
### URLs
|
|
- `BASE_URL`: URL de base du site de la FFA (défaut: `https://athle.fr`)
|
|
- `CLUBS_URL`: URL du site des clubs (défaut: `https://monclub.athle.fr`)
|
|
- `CALENDAR_URL`: URL du calendrier des compétitions
|
|
- `RESULTS_URL`: URL des résultats
|
|
|
|
### Performance
|
|
- `REQUEST_DELAY`: Délai entre les requêtes en secondes (défaut: `2`)
|
|
- `MAX_RETRIES`: Nombre maximum de tentatives pour une requête (défaut: `3`)
|
|
- `TIMEOUT`: Timeout des requêtes en secondes (défaut: `30`)
|
|
- `MAX_WORKERS`: Nombre de workers pour le multithreading (défaut: `4`)
|
|
|
|
### Scraping
|
|
- `DEFAULT_LIMIT_COURSES`: Limite de courses à scraper (défaut: `10000`)
|
|
- `DEFAULT_LIMIT_RESULTS`: Limite de résultats à scraper (défaut: `50000`)
|
|
- `HEADLESS`: Mode headless pour Selenium (défaut: `True`)
|
|
- `WINDOW_SIZE`: Taille de la fenêtre du navigateur (défaut: `1920,1080`)
|
|
|
|
### Logs
|
|
- `LOG_LEVEL`: Niveau de log (DEBUG, INFO, WARNING, ERROR)
|
|
- `LOG_FILE`: Fichier de log (défaut: `ffa_scraper.log`)
|
|
|
|
### CSV
|
|
- `CSV_ENCODING`: Encodage des fichiers CSV (défaut: `utf-8-sig`)
|
|
|
|
## 📖 Utilisation
|
|
|
|
### Via l'interface CLI principale
|
|
|
|
Le script principal `scripts/ffa_cli.py` offre une interface complète.
|
|
|
|
#### 1. Vérifier le nombre de courses disponibles
|
|
|
|
```bash
|
|
python scripts/ffa_cli.py check
|
|
```
|
|
|
|
Cette commande détecte automatiquement:
|
|
- Le nombre total de pages de courses
|
|
- Le nombre estimé de courses
|
|
- Le temps estimé pour le scraping
|
|
|
|
#### 2. Lister les données disponibles
|
|
|
|
```bash
|
|
python scripts/ffa_cli.py list
|
|
```
|
|
|
|
Affiche un résumé des données actuellement disponibles.
|
|
|
|
#### 3. Lancer le scraping des données
|
|
|
|
```bash
|
|
python scripts/ffa_cli.py scrape --max-pages 7
|
|
```
|
|
|
|
Options:
|
|
- `--output`: Répertoire de sortie des données
|
|
- `--limit-courses`: Limiter le nombre de courses à scraper
|
|
- `--limit-results`: Limiter le nombre de résultats à scraper
|
|
- `--fetch-details`: Récupérer les détails et résultats de chaque course
|
|
- `--max-pages`: Nombre maximum de pages à scraper
|
|
- `--multithreading` / `--no-multithreading`: Activer/désactiver le multithreading
|
|
|
|
#### 3.5. Scraping complet par périodes (2010-2026)
|
|
|
|
Pour récupérer toutes les courses de 2010 à 2026 par lots de 15 jours:
|
|
|
|
```bash
|
|
python scripts/scrape_all_periods.py
|
|
```
|
|
|
|
Ce script va:
|
|
- Générer automatiquement 313 périodes de 15 jours
|
|
- Scraper en parallèle avec 8 workers (multithreading)
|
|
- Sauvegarder chaque période dans `data/courses/periods/`
|
|
- Fusionner toutes les données dans `data/courses/courses_list.csv`
|
|
- Exécuter automatiquement les scripts de post-traitement
|
|
|
|
**Résultats:**
|
|
- Fichiers CSV individuels par période : `data/courses/periods/courses_YYYY-MM-DD_to_YYYY-MM-DD.csv`
|
|
- Fichier consolidé : `data/courses/courses_list.csv`
|
|
- Statistiques détaillées par année
|
|
|
|
**Note**: Ce processus peut prendre plusieurs heures selon le nombre de courses et votre connexion internet.
|
|
|
|
#### 4. Rechercher des données
|
|
|
|
**Rechercher un athlète:**
|
|
```bash
|
|
python scripts/ffa_cli.py search athlete --nom "BAZALGETTE" --prenom "Romain"
|
|
```
|
|
|
|
**Rechercher un club:**
|
|
```bash
|
|
python scripts/ffa_cli.py search club --nom "Moissac"
|
|
```
|
|
|
|
**Rechercher des courses par période:**
|
|
```bash
|
|
python scripts/ffa_cli.py search course --start-date "2024-01-01" --end-date "2024-12-31"
|
|
```
|
|
|
|
#### 5. Afficher des statistiques
|
|
|
|
**Statistiques d'un athlète:**
|
|
```bash
|
|
python scripts/ffa_cli.py stats athlete --nom "Dupont" --prenom "Jean"
|
|
```
|
|
|
|
**Classement par club:**
|
|
```bash
|
|
python scripts/ffa_cli.py stats club --course-url "https://athle.fr/competitions/course-123"
|
|
```
|
|
|
|
**Top des athlètes:**
|
|
```bash
|
|
python scripts/ffa_cli.py top --limit 10 --min-results 3
|
|
```
|
|
|
|
#### 6. Exporter des données
|
|
|
|
**Exporter les résultats d'un athlète:**
|
|
```bash
|
|
python scripts/ffa_cli.py export athlete --nom "Dupont" --prenom "Jean" --filename "dupont_jean_results.csv"
|
|
```
|
|
|
|
### Via les scripts autonomes
|
|
|
|
#### Recherche d'athlète
|
|
|
|
```bash
|
|
python scripts/search_athlete.py --nom "Dupont" --prenom "Jean"
|
|
```
|
|
|
|
Options:
|
|
- `--nom`: Nom de famille (obligatoire)
|
|
- `--prenom`: Prénom (optionnel)
|
|
- `--data-dir`: Répertoire des données (défaut: data)
|
|
- `--csv-only`: Utiliser uniquement les fichiers CSV
|
|
|
|
#### Recherche de course
|
|
|
|
```bash
|
|
python scripts/search_race.py --start-date "2024-01-01" --end-date "2024-12-31"
|
|
```
|
|
|
|
#### Extraction des courses
|
|
|
|
```bash
|
|
python scripts/extract_races.py --output data
|
|
```
|
|
|
|
#### Liste des clubs
|
|
|
|
```bash
|
|
python scripts/list_clubs.py
|
|
```
|
|
|
|
#### Résumé par athlète
|
|
|
|
```bash
|
|
python scripts/athlete_summary.py --data-dir data --output athlete_summary.csv
|
|
```
|
|
|
|
#### Extraction des résultats par club
|
|
|
|
**Récupérer tous les résultats d'un club:**
|
|
```bash
|
|
python scripts/get_club_results.py --club "Haute Saintonge Athletisme"
|
|
```
|
|
|
|
**Recherche floue (contient le nom):**
|
|
```bash
|
|
python scripts/get_club_results.py --club "Saintonge" --fuzzy-match
|
|
```
|
|
|
|
**Lister tous les clubs contenant un terme:**
|
|
```bash
|
|
python scripts/get_club_results.py --list-clubs --search-term "Saintonge"
|
|
```
|
|
|
|
Options:
|
|
- `--club`: Nom du club à rechercher
|
|
- `--fuzzy-match`: Recherche floue (défaut: True)
|
|
- `--exact-match`: Recherche exacte du nom
|
|
- `--list-clubs`: Lister tous les clubs disponibles
|
|
- `--search-term`: Terme de recherche pour filtrer les clubs
|
|
- `--limit`: Limiter le nombre de clubs affichés
|
|
- `--output-dir`: Répertoire de sortie pour les exports
|
|
|
|
Les résultats sont exportés dans `data/exports/` avec un fichier CSV contenant tous les résultats du club.
|
|
|
|
#### Scraping des détails et épreuves des courses
|
|
|
|
**Scraper les détails de toutes les courses:**
|
|
```bash
|
|
python scripts/scrape_course_details.py
|
|
```
|
|
|
|
**Scraper un nombre limité de courses:**
|
|
```bash
|
|
python scripts/scrape_course_details.py --limit 100
|
|
```
|
|
|
|
**Reprendre le scraping à partir d'un index:**
|
|
```bash
|
|
python scripts/scrape_course_details.py --start-from 500
|
|
```
|
|
|
|
Ce script génère deux fichiers CSV:
|
|
- `data/course_details.csv`: Détails de chaque course (ID, lieu, site web, etc.)
|
|
- `data/course_epreuves.csv`: Épreuves de chaque course (distance, catégorie, sexe, participants)
|
|
|
|
Options:
|
|
- `--courses-file`: Fichier CSV des courses (défaut: data/courses_daily.csv)
|
|
- `--output-dir`: Répertoire de sortie (défaut: data)
|
|
- `--limit`: Limiter le nombre de courses à scraper
|
|
- `--start-from`: Index de départ pour reprendre le scraping
|
|
|
|
### Via les modules Python
|
|
|
|
```python
|
|
import sys
|
|
sys.path.insert(0, 'src')
|
|
|
|
from ffa_scraper import FFAScraper
|
|
from ffa_analyzer import FFADataAnalyzer
|
|
|
|
# Scraper
|
|
scraper = FFAScraper(output_dir="data")
|
|
stats = scraper.scrap_all_data(max_pages=7, use_multithreading=True)
|
|
|
|
# Analyseur
|
|
analyzer = FFADataAnalyzer(data_dir="data")
|
|
results = analyzer.search_athlete("Dupont", "Jean")
|
|
```
|
|
|
|
## 📊 Structure des données
|
|
|
|
### Fichiers générés
|
|
|
|
```
|
|
data/
|
|
├── courses/
|
|
│ └── periods/
|
|
│ ├── courses_2010-01-01_to_2010-01-15.csv
|
|
│ ├── courses_2010-01-16_to_2010-01-30.csv
|
|
│ └── ...
|
|
├── resultats/
|
|
│ └── results.csv
|
|
├── clubs/
|
|
│ └── clubs.csv
|
|
└── exports/
|
|
└── athlete_dupont_jean.csv
|
|
```
|
|
|
|
### Format des CSV
|
|
|
|
#### courses_*.csv
|
|
- nom: Nom de la course
|
|
- date: Date de la course
|
|
- lieu: Lieu de la course
|
|
- lien: URL vers la page de la course
|
|
- type: Type de course (Cross, Stade, Route, etc.)
|
|
- categorie: Catégorie de la compétition
|
|
- resultats_url: URL vers la page des résultats
|
|
|
|
#### results.csv
|
|
- place: Place obtenue
|
|
- nom: Nom de l'athlète (en majuscules)
|
|
- prenom: Prénom de l'athlète
|
|
- club: Club de l'athlète
|
|
- categorie: Catégorie de compétition
|
|
- temps: Temps réalisé
|
|
- course_url: URL de la course concernée
|
|
|
|
#### course_details.csv (généré par scrape_course_details.py)
|
|
- course_id: ID unique de la course
|
|
- course_url: URL de la page des résultats
|
|
- course_nom: Nom de la course
|
|
- course_date: Date de la course
|
|
- course_lieu: Lieu de la course
|
|
- course_lieu_complet: Lieu détaillé
|
|
- course_site_web: Lien vers le site web de la course
|
|
- competition_id: Numéro de compétition FFA (frmcompetition)
|
|
- organisateur: Organisateur de la course
|
|
- contact: Informations de contact
|
|
- date_heure: Date et heure de la course
|
|
- lieu_details: Détails du lieu
|
|
- nb_epreuves: Nombre d'épreuves
|
|
|
|
#### course_epreuves.csv (généré par scrape_course_details.py)
|
|
- course_id: ID unique de la course
|
|
- epreuve_id: ID unique de l'épreuve
|
|
- epreuve_nom: Nom complet de l'épreuve
|
|
- epreuve_numero: Numéro de l'épreuve dans la course
|
|
- epreuve_distance: Distance (ex: 100m, 10km)
|
|
- epreuve_categorie: Catégorie (ex: Seniors, Vétérans)
|
|
- epreuve_sexe: Sexe (M/F)
|
|
- epreuve_type: Type d'épreuve (Piste, Cross, Trail, Route, Relais)
|
|
- participants: Nombre de participants
|
|
- url_resultats: URL des résultats
|
|
- nom: Nom de la course
|
|
- date: Date de la course
|
|
- lieu: Lieu de la course
|
|
- lien: URL vers la page de la course
|
|
- type: Type de course (Cross, Stade, Route, etc.)
|
|
- categorie: Catégorie de la compétition
|
|
|
|
#### results.csv
|
|
- place: Place obtenue
|
|
- nom: Nom de l'athlète (en majuscules)
|
|
- prenom: Prénom de l'athlète
|
|
- club: Club de l'athlète
|
|
- categorie: Catégorie de compétition
|
|
- temps: Temps réalisé
|
|
- course_url: URL de la course concernée
|
|
|
|
## 🛠️ Scripts disponibles
|
|
|
|
### Scripts principaux
|
|
|
|
| Script | Description |
|
|
|--------|-------------|
|
|
| `ffa_cli.py` | Interface CLI principale |
|
|
| `search_athlete.py` | Recherche d'athlètes dans les résultats |
|
|
| `search_race.py` | Recherche de courses par période |
|
|
| `extract_races.py` | Extraction des courses depuis le calendrier |
|
|
|
|
### Scripts utilitaires
|
|
|
|
| Script | Description |
|
|
|--------|-------------|
|
|
| `list_clubs.py` | Liste les clubs disponibles |
|
|
| `post_process.py` | Post-traitement des données scrapées |
|
|
| `monitor_scraping.py` | Surveillance en temps réel du scraping |
|
|
| `scrape_all_periods.py` | Scraping complet par périodes |
|
|
| `athlete_summary.py` | Génération de résumés par athlète |
|
|
| `get_club_results.py` | Extraction des résultats d'un club |
|
|
| `scrape_course_details.py` | Scraping des détails et épreuves des courses |
|
|
|
|
## 🚀 Performance
|
|
|
|
### Multithreading
|
|
|
|
Le multithreading est activé par défaut et utilise 4 workers simultanés. Chaque worker utilise son propre driver Selenium pour scraper les pages en parallèle.
|
|
|
|
**Comparaison de performance:**
|
|
- Séquentiel: ~14 secondes pour 7 pages
|
|
- Multithreading (4 workers): ~8 secondes
|
|
- Gain: ~43% plus rapide
|
|
|
|
**Recommandations pour le nombre de workers:**
|
|
- 2-4 workers: Machines avec 4-8 Go de RAM
|
|
- 4-8 workers: Machines avec 8-16 Go de RAM
|
|
- 8-16 workers: Machines avec 16+ Go de RAM
|
|
|
|
Note: Chaque driver Chrome consomme ~200-300 Mo de RAM.
|
|
|
|
## 📝 Version
|
|
|
|
### v1.3.0 (Dernière mise à jour)
|
|
- **Nouveau**: Script `get_club_results.py` pour extraire les résultats d'un club depuis le CSV
|
|
- **Nouveau**: Script `scrape_course_details.py` pour récupérer les détails et épreuves des courses
|
|
- **Nouveau**: Extraction des numéros de compétition (frmcompetition)
|
|
- **Nouveau**: Extraction des épreuves avec distance, catégorie et sexe
|
|
- **Nouveau**: Extraction des liens vers les sites web des courses
|
|
- **Amélioré**: Recherche flexible de clubs avec correspondance floue
|
|
|
|
### v1.2.0
|
|
- **Nouveau**: Multithreading pour accélérer le scraping (4 workers par défaut)
|
|
- **Nouveau**: Commande `check` pour détecter le nombre total de pages et de courses
|
|
- **Nouveau**: Détection automatique de la pagination et estimation du temps
|
|
- **Amélioré**: Scraping beaucoup plus rapide (4x plus rapide avec multithreading)
|
|
- **Amélioré**: Barre de progression en temps réel avec tqdm
|
|
- **Nouveau**: Options `--multithreading` et `--no-multithreading`
|
|
|
|
### v1.1.0
|
|
- **Nouveau**: Ajout de la commande `list` pour voir les données disponibles
|
|
- **Nouveau**: Ajout de la commande `top` pour voir les meilleurs athlètes
|
|
- **Nouveau**: Recherche par club dans les résultats
|
|
- **Amélioré**: Intégration de `config.env` pour la configuration
|
|
- **Amélioré**: Support de pagination multi-pages pour le calendrier
|
|
- **Nettoyé**: Code optimisé et documenté
|
|
|
|
## ⚠️ Notes importantes
|
|
|
|
### Fonctionnalités actuelles
|
|
|
|
**✓ Fonctionne:**
|
|
- Scraping du calendrier des compétitions (2010-2026)
|
|
- Détection automatique de la pagination
|
|
- Multithreading pour un scraping 4x plus rapide
|
|
- 250+ compétitions récupérées par page
|
|
- Scraping des résultats des compétitions
|
|
- Recherche d'athlètes, clubs et courses
|
|
- Analyse et export des données
|
|
- Barre de progression en temps réel
|
|
|
|
**⚠️ Limitations:**
|
|
- Le site `monclub.athle.fr` nécessite une connexion pour accéder aux données des clubs
|
|
- Les résultats individuels nécessitent un scraping détaillé (option `--fetch-details`)
|
|
- Le multithreading utilise plusieurs drivers Selenium (attention à la RAM)
|
|
- Le scraping doit être utilisé de manière responsable (pauses entre les requêtes)
|
|
- La structure HTML du site peut changer et nécessiter des mises à jour
|
|
|
|
### Améliorations possibles
|
|
|
|
- Implémentation de l'authentification pour `monclub.athle.fr`
|
|
- Ajout d'une base de données locale pour des performances accrues
|
|
- Interface web pour faciliter l'utilisation
|
|
- Support pour la reprise d'un scraping interrompu
|
|
- Tests unitaires complets
|
|
- Documentation API des modules
|
|
|
|
## 🤝 Contribuer
|
|
|
|
Les contributions sont les bienvenues ! N'hésitez pas à:
|
|
|
|
1. Forker le projet
|
|
2. Créer une branche pour votre fonctionnalité (`git checkout -b feature/AmazingFeature`)
|
|
3. Committer vos changements (`git commit -m 'Add some AmazingFeature'`)
|
|
4. Pusher vers la branche (`git push origin feature/AmazingFeature`)
|
|
5. Ouvrir une Pull Request
|
|
|
|
## 📄 Licence
|
|
|
|
Ce projet est sous licence MIT. Voir le fichier [LICENSE](LICENSE) pour plus de détails.
|
|
|
|
## 📞 Contact
|
|
|
|
Pour toute question ou suggestion, n'hésitez pas à:
|
|
- Ouvrir une issue sur GitHub
|
|
- Contacter le mainteneur du projet
|
|
|
|
---
|
|
|
|
**Note importante**: Ce scraper doit être utilisé de manière responsable. Respectez les conditions d'utilisation du site de la FFA et évitez les requêtes excessives.
|