Aller au contenu
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.

Analyse de donnéesAPIDocker
PythonpandasPolarsPyPDF2JupyterFastAPIBeautifulSouppre-commit
  • Mis à jour

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.

Diagramme de cas d’utilisation de Salary : Extraire les guides PDF; Charger les salaires 2012-2022; Comparer métiers et régions; Collecter Stack Overflow; Interroger l’API des salairesSalaryExtraire les guides PDFCharger les salaires 2012-2022Comparer métiers et régionsCollecter Stack OverflowInterroger l’API des salairesAnalyste des salairesClient de l’API«système»Sondage Stack Overflow
Acteurs à gauche (personnes) et à droite (systèmes externes) ; chaque ovale est un cas d’utilisation appuyé par les fichiers cités ci-dessous.
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

  1. Lancer pip install -r requirements.txt à la racine du dépôt.
  2. Placer 2023_salary_guide.pdf dans data/pdf et lancer python src/pdf_salary_scraper_2023_1.py.
  3. Vérifier que data/pickle/salary_guide_2023.pkl a été créé.
  4. Démarrer jupyter notebook et ouvrir sandbox/salary_exploration_2023.ipynb, qui sépare chaque fourchette et calcule les moyennes par niveau.
  5. 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écompteLignes
Lignes avec des fourchettes de salaire19 387
Dans des tableaux débutant / intermédiaire / senior17 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 restantes14 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.

Diagramme en barres horizontales du salaire intermédiaire médian par famille d’emplois : technologies 97,2 k$, ingénierie 81,8 k$, marketing 81,7 k$, ressources humaines 76,5 k$, fabrication 75,3 k$, ventes 64,7 k$, santé 57,0 k$, soutien administratif 54,8 k$, expérience client 54,8 k$
Salaire intermédiaire médian par famille d’emplois dans le guide 2023. Les emplois technos se situent environ 15 k$ au-dessus de l’ingénierie et du marketing.

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.

Diagramme en barres horizontales du salaire intermédiaire médian par province, de l’Alberta à 85,2 k$ à l’Île-du-Prince-Édouard à 70,3 k$
Salaire intermédiaire médian par province. Les emplois listés varient d’une province à l’autre : comparez un même emploi d’une ville à l’autre avant de conclure.

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.

Diagramme en barres groupées du salaire intermédiaire de sept emplois technos à Montréal, dans le Grand Toronto, le Grand Vancouver et à Calgary
Milieux intermédiaires de sept emplois technos dans quatre métropoles. Les salaires des développeurs sont proches d’une ville à l’autre ; ceux du soutien, non.

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.

Graphique en barres du carnet, salaires maximums 2023 et 2024, avec 713 k$ pour les deux années au niveau senior
Le graphique enregistré dans le carnet : les deux barres senior montrent la valeur aberrante de 713 k$, celle de 2024 à cause d’un copier-coller du tableau 2023.

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.py et src/pdf_salary_scraper_2024_1.py extraient les guides 2023 et 2024 (le README indique Randstad comme source) ; les scripts _2 et generic_wip en sont des variantes sous forme de fonctions.
  • src/wages_in_time.py combine les tableaux de salaires 2012 à 2022 du Guichet-Emplois.
  • src/stackoverflow_scraper.py récupère le tableau des salaires du sondage Stack Overflow.
  • src/analyse.py et src/utils.py regroupent les fonctions d’analyse et de pickle ; src/__init__.py liste provinces et régions.
  • sandbox/ contient les carnets d’exploration 2023 et 2024 et une comparaison 2023-2024.
  • data/pdf/, data/csv/, data/pickle/ et data/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.md décrit les colonnes des salaires.
  • api/ contient l’application FastAPI, le Dockerfile, le fichier Compose et les notes de déploiement.
  • web/index.html présente des résultats 2023 en texte statique ; web/job_search.html est 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.py et un stackoverflow_scraper.py à la racine, qui n’existent pas sous ces noms.
  • requirements.txt omet PyMuPDF, Polars et BeautifulSoup, que les scripts importent ; src/wages_in_time.py utilise 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.html donnent une réceptionniste bilingue à 713 000 $ comme salaire le plus élevé de 2023, signe d’erreurs d’extraction.
  • src/wages_in_time.py annualise 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.json construit un app.py à la racine alors que l’application est api/app.py, le Dockerfile lance unicorn sur le port 8000 alors que Compose publie le port 5000, et l’API lit les pickles par des chemins relatifs ../data.
  • src/test.py importe des fonctions qui n’existent pas, et setup.py pointe encore vers un répertoire de paquet code avec une description héritée d’un gabarit.

8. Sources

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
Dépendances externes
PaquetVersionUsageRôleRegistre
python-dotenv==0.21.1exécutionConfigurationpypi.org
backtesting==0.3.3exécutionTestspypi.org
pandas==1.4.0exécutionAnalyse de donnéespypi.org
numpy==1.24.2exécutionAnalyse de donnéespypi.org
matplotlib==3.5.1exécutionGraphiquespypi.org
seaborn==0.11.2exécutionGraphiquespypi.org
PyPDF2==3.0.1exécutionA pure-python PDF library capable of splitting, merging, cropping, and transforming PDF filespypi.org
dash==2.8.1exécutionInterface utilisateurpypi.org
fastapi—exécutionCadriciel webpypi.org
uvicorn—exécutionServeur d’applicationpypi.org
jinja2—exécutionGabaritspypi.org
pydantic—exécutionValidation des donnéespypi.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

  1. AlgoETS. (2026, 5 novembre). Salary. [Software repository] github.com.
  2. AlgoETS. (2026, 5 novembre). README. [Source file or documentation] github.com.
  3. AlgoETS. (2026, 5 novembre). src/pdf_salary_scraper_2024_1.py. [Source file or documentation] github.com.
  4. AlgoETS. (2026, 5 novembre). src/wages_in_time.py. [Source file or documentation] github.com.
  5. AlgoETS. (2026, 5 novembre). sandbox/salary_exploration_2023.ipynb. [Source file or documentation] github.com.
  6. AlgoETS. (2026, 5 novembre). sandbox/compare_2023_to_2024.ipynb. [Source file or documentation] github.com.
  7. AlgoETS. (2026, 5 novembre). sandbox/output/output.txt. [Source file or documentation] github.com.
  8. AlgoETS. (2026, 5 novembre). api/app.py. [Source file or documentation] github.com.
  9. 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.