Table des matières
Salary
Salary est un projet de données d’AlgoÉTS sur la rémunération au Canada. Il transforme des guides salariaux de firmes de recrutement (PDF) et des tableaux de salaires fédéraux (CSV) en tableaux de données, puis compare les postes entre provinces, régions et niveaux d’expérience. Il sert à voir, par exemple, comment un architecte infonuagique est payé d’une région à l’autre, et intéressera aussi ceux qui veulent extraire des tableaux de rapports PDF.
1. Aperçu
L’extraction des PDF repose sur un script par édition de guide. src/pdf_salary_scraper_2023_1.py et src/pdf_salary_scraper_2024_1.py lisent un guide de data/pdf/ avec PyPDF2, suivent la province et la région courantes à partir de listes de noms fixes, séparent chaque ligne en un titre de poste et trois fourchettes (junior, intermédiaire et senior) et enregistrent le résultat en pickle dans data/pickle/. src/pdf.py est un essai antérieur avec PyMuPDF qui étiquette le texte selon la taille de police pour repérer les titres.
src/wages_in_time.py charge les fichiers du Guichet-Emplois data/csv/wage_2012.csv à wage_2022.csv avec Polars, harmonise les noms de colonnes d’une année à l’autre, met la table combinée en cache dans data/pickle/wages.pkl et affiche les postes les mieux payés par année ainsi que les postes d’ingénierie les mieux payés par province. src/stackoverflow_scraper.py récupère le tableau des salaires du sondage Stack Overflow 2022.
L’analyse se fait dans sandbox/salary_exploration_2023.ipynb et sandbox/salary_exploration_2024.ipynb, avec des versions des mêmes fonctions dans src/analyse.py : séparer les fourchettes, calculer les moyennes par niveau, classer les postes, filtrer l’ingénierie et le Québec, comparer un poste entre régions et provinces et trouver les postes aux plus grands écarts régionaux. api/app.py expose les pickles 2023 et 2024 en JSON avec FastAPI, et web/ contient deux pages HTML statiques.
2. Cas d’utilisation
Scripts et carnets Python qui extraient des guides salariaux et tableaux de salaires canadiens pour comparer métiers et régions.
- Extraire les guides PDF
- Analyste des salaires
src/pdf_salary_scraper_2023_1.py et src/pdf_salary_scraper_2024_1.py lisent un guide de data/pdf avec PyPDF2, suivent province et région, extraient les fourchettes junior, intermédiaire et senior par poste et enregistrent un pickle dans data/pickle.
- Charger les salaires 2012-2022
- Analyste des salaires
src/wages_in_time.py lit data/csv/wage_2012.csv à wage_2022.csv avec Polars, harmonise les colonnes, met en cache data/pickle/wages.pkl et affiche les postes les mieux payés par année et les postes d’ingénierie par province.
- Comparer métiers et régions
- Analyste des salaires
sandbox/salary_exploration_2023.ipynb et salary_exploration_2024.ipynb classent les postes par salaire maximal, filtrent l’ingénierie et le Québec, comparent un poste entre régions et provinces et trouvent les plus grands écarts.
- Collecter Stack Overflow
- Analyste des salairesSondage Stack Overflow
src/stackoverflow_scraper.py récupère la page des salaires du sondage Stack Overflow 2022 avec httpx, lit le tableau avec BeautifulSoup et l’enregistre dans data/pickle/stackoverflow_salary_data.pkl.
- Interroger l’API des salaires
- Client de l’API
api/app.py est une application FastAPI dont les routes /load_pickle/2023 et /salary/2024 renvoient les guides en JSON ; la documentation interactive est à /docs.
2.1. Scénario : Comparer le salaire d’architecte infonuagique au Québec
- Lancer pip install -r requirements.txt à la racine du dépôt.
- Placer 2023_salary_guide.pdf dans data/pdf et lancer python src/pdf_salary_scraper_2023_1.py.
- Vérifier que data/pickle/salary_guide_2023.pkl a été créé.
- Démarrer jupyter notebook et ouvrir sandbox/salary_exploration_2023.ipynb, qui sépare chaque fourchette et calcule les moyennes par niveau.
- Appeler compare_job_province('cloud architect', 'québec') pour classer les régions du Québec selon le salaire intermédiaire moyen.
Fichiers consultésREADME.mdrequirements.txtsetup.pyvercel.jsonapi/app.pyapi/Dockerfileapi/docker-compose.ymlapi/setup.mdsrc/pdf.pysrc/pdf_salary_scraper_2023_1.pysrc/pdf_salary_scraper_2024_1.pysrc/stackoverflow_scraper.pysrc/wages_in_time.pysrc/analyse.pysrc/test.pydata/csv/README.mddata/pdf/README.mdsandbox/salary_exploration_2023.ipynbsandbox/salary_exploration_2024.ipynbweb/index.htmlweb/job_search.html
3. Résultats du guide 2023
Le dépôt conserve le texte brut du guide 2023 (le README cite Randstad comme source) dans sandbox/output/output.txt : une ligne par cellule de tableau, marquée du niveau de titre d’où elle vient. Relire ce fichier en gardant les en-têtes de tableau, au lieu de supposer que chaque ligne est débutant / intermédiaire / senior, donne les chiffres ci-dessous. Tous les montants sont ceux du guide, en milliers de dollars par an, et chaque chiffre est la médiane des milieux de fourchette (pour « 75.0 - 90.0 », le milieu vaut 82,5). L’article associé, Ce que dit un guide salarial canadien quand on lit bien ses tableaux, raconte la même analyse avec plus de contexte.
Ce que contient le fichier.
| Décompte | Lignes |
|---|---|
| Lignes avec des fourchettes de salaire | 19 387 |
| Dans des tableaux débutant / intermédiaire / senior | 17 915 |
| Dans des tableaux par années d’expérience (1, 3, 5, 10 ans) | 760 |
| Dans des tableaux par chiffre d’affaires (10 M$, 100 M$, 1 000 M$) | 677 |
| Doublons exacts (même emploi, région et province) | 3 607 |
| Fourchettes cassées (haut au-delà de trois fois le bas, ou sous le bas) | 3 |
| Lignes emploi-région propres restantes | 14 305 |
Les 1 437 lignes des tableaux par expérience et par chiffre d’affaires concernent la finance et les RH. Les scripts d’extraction les lisent comme débutant, intermédiaire et senior : c’est ainsi qu’un chef de la direction financière d’une entreprise de 1 000 M$ de chiffre d’affaires (594,1 k$ en haut de fourchette) devient un salaire « senior » dans les carnets. Parmi les lignes propres, les 1 242 de la famille soutien industriel sont des taux horaires (19,8 $, 22,3 $ et 24,9 $ de l’heure selon le niveau) ; elles sont donc séparées des 13 063 lignes annuelles, qui couvrent 371 emplois dans 57 régions.
Niveaux. Le milieu médian vaut 66,2 k$ au niveau débutant, 75,9 k$ au niveau intermédiaire et 86,8 k$ au niveau senior. Le pas entre niveaux est très régulier : pour l’emploi médian, le salaire senior vaut 1,30 fois le salaire débutant, et 80 % des lignes se situent entre 1,22 et 1,36.
Provinces. L’Alberta a le milieu intermédiaire médian le plus élevé (85,2 k$), suivie de la Colombie-Britannique (81,8 k$) et de la Saskatchewan (78,4 k$) ; le Québec (71,4 k$) et l’Île-du-Prince-Édouard (70,3 k$) ferment la marche. Ces médianes mélangent les emplois que chaque région liste, et le Québec compte à lui seul 16 régions, la plupart hors de Montréal : l’écart vient donc en partie des emplois et des lieux comptés, pas seulement du salaire pour un même emploi.
Un même emploi, quatre villes. Comparer un seul emploi entre régions retire l’effet de composition. Pour les développeurs et les architectes, les quatre métropoles sont à moins d’environ 10 % les unes des autres : un développeur full stack intermédiaire est à 112,4 k$ à Montréal, 120,2 k$ dans le Grand Toronto, 115,1 k$ dans le Grand Vancouver et 111,7 k$ à Calgary, et le poste DevOps (développement) est le mieux payé à Montréal, à 110,0 k$. L’exception est le soutien : un analyste de centre d’assistance intermédiaire est à 61,6 k$ à Montréal contre 78,7 k$ dans le Grand Toronto.
Emplois les mieux payés. Parmi les emplois listés dans au moins 25 régions, les milieux intermédiaires médians les plus élevés sont directeur des opérations (190,4 k$), directeur du commerce électronique (159,7 k$), directeur de construction (153,6 k$), directeur de fabrication (153,3 k$) et directeur de l’approvisionnement (152,3 k$). Côté technologies, viennent en tête directeur des TI (151,8 k$), responsable technique (143,1 k$) et architecte d’applications (132,2 k$).
Ce que montre plutôt le carnet de comparaison. sandbox/compare_2023_to_2024.ipynb compare directement les fichiers pickle 2023 et 2024. Son graphique des salaires maximums place « receptionist (bilingual) » à 713 k$, la ligne cassée du comté de Simcoe, et affiche les mêmes 713 k$ pour 2024, parce que les listes de minimums et de maximums 2024 lisent leur valeur senior dans df_sorted_2023. Dans le pickle 2024, entry_max a exactement la même moyenne (94,67) et le même écart-type que mid_max, signe d’une fourchette débutant assemblée avec les mauvais nombres. Le guide 2024 est aussi en français (ingénieur·e chimiste) alors que celui de 2023 est en anglais : on ne peut pas apparier les emplois des deux années par leur titre.

4. Démarrage
Le README donne ces étapes :
pip install -r requirements.txt
python src/pdf.py
jupyter notebook
Lancez les scripts d’extraction depuis la racine du dépôt, car ils utilisent des chemins comme data/pdf/2023_salary_guide.pdf :
python src/pdf_salary_scraper_2023_1.py
python src/wages_in_time.py
api/setup.md décrit le déploiement de l’API avec Docker et Vercel ; en local, on peut la démarrer avec uvicorn depuis le répertoire api/ :
cd api
uvicorn app:app --reload
5. Guide du dépôt
src/pdf_salary_scraper_2023_1.pyetsrc/pdf_salary_scraper_2024_1.pyextraient les guides 2023 et 2024 (le README indique Randstad comme source) ; les scripts_2etgeneric_wipen sont des variantes sous forme de fonctions.src/wages_in_time.pycombine les tableaux de salaires 2012 à 2022 du Guichet-Emplois.src/stackoverflow_scraper.pyrécupère le tableau des salaires du sondage Stack Overflow.src/analyse.pyetsrc/utils.pyregroupent les fonctions d’analyse et de pickle ;src/__init__.pyliste provinces et régions.sandbox/contient les carnets d’exploration 2023 et 2024 et une comparaison 2023-2024.data/pdf/,data/csv/,data/pickle/etdata/geo/contiennent les guides de plusieurs firmes de recrutement, les tableaux de salaires, les pickles extraits et des fichiers de formes des provinces ;data/csv/README.mddécrit les colonnes des salaires.api/contient l’application FastAPI, le Dockerfile, le fichier Compose et les notes de déploiement.web/index.htmlprésente des résultats 2023 en texte statique ;web/job_search.htmlest une maquette de formulaire de recherche.
6. Fonctionnalités
- extraire poste, province, région et fourchettes junior, intermédiaire et senior des guides salariaux en PDF ;
- réunir onze années de tableaux de salaires du Guichet-Emplois dans un seul tableau Polars ;
- classer les postes selon le salaire maximal, au total, par année, par province et pour l’ingénierie ;
- comparer un poste entre régions et provinces et trouver les plus grands écarts régionaux ;
- récupérer les salaires du sondage Stack Overflow ;
- servir les guides 2023 et 2024 extraits en JSON avec FastAPI.
7. Limites
- Le README annonce un modèle de prédiction des salaires selon la région, l’expérience et la scolarité ; le dépôt contient du code d’extraction et d’exploration, mais aucun modèle.
- Les commandes du README nomment
src/pdf_salary_scraper.pyet unstackoverflow_scraper.pyà la racine, qui n’existent pas sous ces noms. requirements.txtomet PyMuPDF, Polars et BeautifulSoup, que les scripts importent ;src/wages_in_time.pyutilise une ancienne API de Polars.- La province et la région viennent du premier nom d’une liste fixe trouvé n’importe où sur la page, la fourchette junior joint le bas de la première paire au haut de la deuxième, et les lignes à quatre fourchettes sont ignorées. Le README et
web/index.htmldonnent une réceptionniste bilingue à 713 000 $ comme salaire le plus élevé de 2023, signe d’erreurs d’extraction. src/wages_in_time.pyannualise les salaires horaires avec 40 × 45 heures dans une fonction et 45 × 45 dans une autre, et signale les fichiers 2017 et 2018 comme mal formatés.- Les fichiers de déploiement se contredisent :
vercel.jsonconstruit unapp.pyà la racine alors que l’application estapi/app.py, le Dockerfile lanceunicornsur le port 8000 alors que Compose publie le port 5000, et l’API lit les pickles par des chemins relatifs../data. src/test.pyimporte des fonctions qui n’existent pas, etsetup.pypointe encore vers un répertoire de paquetcodeavec une description héritée d’un gabarit.
8. Sources
- Dépôt GitHub
- README
src/pdf_salary_scraper_2024_1.pysrc/wages_in_time.pysandbox/salary_exploration_2023.ipynbsandbox/compare_2023_to_2024.ipynbsandbox/output/output.txtapi/app.pydata/csv/README.md
9. Pipeline CI/CD
Aucun pipeline CI/CD dans le dépôt. Le code se construit et se lance à la main, comme décrit plus haut.
Généré à partir du code au commit 40b10f4.
10. Schéma de déploiement
Mermaid Schéma de déploiement
flowchart LR
repo[("Dépôt GitHub")]
image["Image Docker<br/>FROM python:3.12.0rc3-slim"]
host_Vercel("Vercel<br/>vercel.json")
repo -->|"docker build"| image
repo -.->|"configuré"| host_Vercel
11. Dépendances externes
12 paquets déclarés (12 à l’exécution, 0 pour le développement) dans requirements.txt, api/requirements.txt.
Tableau des paquets 12
| Paquet | Version | Usage | Rôle | Registre |
|---|---|---|---|---|
python-dotenv | ==0.21.1 | exécution | Configuration | pypi.org |
backtesting | ==0.3.3 | exécution | Tests | pypi.org |
pandas | ==1.4.0 | exécution | Analyse de données | pypi.org |
numpy | ==1.24.2 | exécution | Analyse de données | pypi.org |
matplotlib | ==3.5.1 | exécution | Graphiques | pypi.org |
seaborn | ==0.11.2 | exécution | Graphiques | pypi.org |
PyPDF2 | ==3.0.1 | exécution | A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files | pypi.org |
dash | ==2.8.1 | exécution | Interface utilisateur | pypi.org |
fastapi | — | exécution | Cadriciel web | pypi.org |
uvicorn | — | exécution | Serveur d’application | pypi.org |
jinja2 | — | exécution | Gabarits | pypi.org |
pydantic | — | exécution | Validation des données | pypi.org |
12. Glossaire
Dépôt
Les fichiers source, la configuration et l’historique versionné d’un projet.
README
Le document d’entrée du dépôt, qui présente généralement son rôle et son installation.
Dépendance
Une bibliothèque, un outil ou un service nécessaire à la compilation ou à l’exécution d’un composant.
API
Une interface par laquelle des composants logiciels échangent des requêtes et des résultats. Une API n’utilise pas nécessairement HTTP.
HTTP
Un protocole de requête et réponse utilisé par les navigateurs et services web. Une requête comprend une méthode, un chemin, des en-têtes et parfois un corps.
Conteneur
Un environnement de processus isolé créé à partir d’une image. Les données persistantes nécessitent un stockage hors de son système de fichiers temporaire.
Docker Compose
Un format de configuration et un outil pour lancer des conteneurs, réseaux et volumes associés. L’ordre de démarrage ne garantit pas qu’un service est prêt.
Port publié
Un port de l’hôte associé au port d’un service dans un conteneur. Sa publication peut rendre le service accessible hors du réseau des conteneurs.
Interface en ligne de commande
Une interface textuelle où les commandes et arguments choisissent les opérations. Les codes de retour permettent aux scripts de détecter un succès ou un échec.
Intégration continue
Des vérifications automatiques lors des changements de source, comme la compilation, les tests et l’analyse statique. Elles ne couvrent que ce qu’elles vérifient.
Mermaid
Un langage de diagrammes textuel. Les nœuds et liens décrivent un modèle ; le diagramme n’exécute pas le projet.
Backend
Une implémentation derrière une interface commune. Selon le contexte, il peut s’agir d’un service côté serveur ou d’une implémentation graphique, d’entrée ou de stockage.
13. Références
- AlgoETS. (2026, 5 novembre). Salary. [Software repository] github.com.
- AlgoETS. (2026, 5 novembre). README. [Source file or documentation] github.com.
- AlgoETS. (2026, 5 novembre). src/pdf_salary_scraper_2024_1.py. [Source file or documentation] github.com.
- AlgoETS. (2026, 5 novembre). src/wages_in_time.py. [Source file or documentation] github.com.
- AlgoETS. (2026, 5 novembre). sandbox/salary_exploration_2023.ipynb. [Source file or documentation] github.com.
- AlgoETS. (2026, 5 novembre). sandbox/compare_2023_to_2024.ipynb. [Source file or documentation] github.com.
- AlgoETS. (2026, 5 novembre). sandbox/output/output.txt. [Source file or documentation] github.com.
- AlgoETS. (2026, 5 novembre). api/app.py. [Source file or documentation] github.com.
- AlgoETS. (2026, 5 novembre). data/csv/README.md. [Source file or documentation] github.com.
Les sources sans date de publication indiquent la date de leur dernière vérification, le 5 novembre 2026. Les liens des fichiers conservent la révision inspectée lorsqu’elle est disponible.