Job Scraper 02
2026 — en coursv0.3.0 sur PyPI & GHCR · en amélioration vers une 1.0
Un scraper FastAPI et un tableau de bord Streamlit dans deux conteneurs, pilotés par une API REST que l'interface se trouve juste à appeler. Colle ton CV et quelques mots-clés, clique Démarrer, et il cherche sur plusieurs sites d'emploi et classe chaque résultat de 0 à 10 par rapport à toi. Je l'ai construit pendant ma recherche d'emploi et il m'a trouvé le job. C'est un vrai paquet sur PyPI maintenant, avec une chaîne de release qui fait plus que taguer un commit.
Rôle — Développeur unique — l'outil, l'empaquetage, et la chaîne de release
- Sur PyPI
- pip install job-scraper02
- Version
- v0.3.0
- Tests
- 26 · la CI lance la vraie app
- Images de conteneur
- 3 (scraper · ui · tout-en-un)
- Fournisseurs d'IA
- 3 + Lite Mode sans clé
- PyPI downloads/mo
- 138
- GitHub release downloads
- 0
La contrainte qui l'a façonné
Il tourne sans aucune clé d'API. Apporte une clé Groq, Anthropic ou Gemini pour une pertinence notée par IA, ou reste en Lite Mode — correspondance par mots-clés, sans clé, sans inscription. Tout atterrit dans un fichier SQLite local qui t'appartient, et rien ne quitte la machine à moins de configurer une clé d'IA ou un webhook. Un outil qui exige un identifiant payant avant de te montrer quoi que ce soit est un outil que personne n'essaie.
À quoi ça ressemble
3 écrans · cliquer pour agrandirLa décision que je défendrais devant n'importe qui
Le scoring par IA est optionnel, pas requis. Sans clé, il retombe sur la correspondance par mots-clés, classe quand même les annonces et marche quand même. C'est tout l'argument : un outil d'emploi qui te fait t'inscrire à une API payante avant de te montrer quoi que ce soit est un outil d'emploi que tu fermes.
Tout ce que fait le tableau de bord est aussi un endpoint REST et une commande CLI, donc ça se câble dans ta propre automatisation. Il y a un profil n8n optionnel si tu veux un moteur d'automatisation complet, et des configs en un clic pour Railway et Render. Le défaut reste docker compose up sur ta propre machine, avec un fichier SQLite que tu gardes.
v0.3.0 — une release qui devait prouver que l'app tourne
Le Lite Mode notait chaque annonce à zéro depuis sa sortie. Un bug de regex faisait qu'aucune annonce ne matchait jamais, quel que soit son rapport au CV. Aucune erreur, rien dans les logs — le mode de défaillance qui fait qu'une fonctionnalité a l'air présente et ne sert à rien. Corrigé, avec des tests de non-régression couvrant match, non-match, limite de mot et plafond de score.
Les notifications étaient mortes par défaut — le seuil d'alerte était 70 sur une échelle qui ne va qu'à 10. Les résultats n'étaient pas triés par score, malgré le README qui affirme que les scores élevés remontent. Deux scrapes pouvaient se courir après s'ils étaient déclenchés coup sur coup ; le verrou de run est atomique maintenant. Le `Dockerfile` simple que la plupart des plateformes auto-détectent ne démarrait que l'interface, sans back-end attaché, donc il était inutilisable sans le dire.
La CI prouve maintenant que l'app marche, pas qu'elle compile. Elle construit le wheel et vérifie que rien n'a fuité hors du paquet, installe et lance le vrai script console job-scraper, et pilote un vrai scrape contre les conteneurs en marche en vérifiant qu'une annonce réellement notée revient. La même leçon que sur tous mes autres projets : un pipeline vert qui n'a lancé que le type checker ne veut rien dire.
Empaqueté correctement. Les modules plats de haut niveau db / app / scraper sont passés dans un vrai paquet job_scraper, pour que l'installer ne puisse pas entrer en collision avec le module db de quelqu'un d'autre dans son environnement.
Comment ça a été construit
11 février 2026
Job Scraper 02
Construit pour moi-même parce que j'en avais assez de consulter dix sites d'emploi chaque matin. Il tourne sans aucune clé d'API — un outil qui exige un identifiant payant pour se démontrer est un outil que personne n'essaie.
24 avril 2026
Job Scraper publié sur PyPI
Via un pipeline GitHub Actions Trusted Publisher, avec deux images de conteneur à côté.