Vous avez une page web que vous ouvrez régulièrement pour vérifier si quelque chose a changé ? Une inscription qui doit ouvrir, un mot-clé qui doit apparaître, ou une annonce que vous attendez ? À force, on finit par actualiser la page plus souvent que nécessaire.

Avec webpagecheck, l’idée est simple : laisser un outil surveiller ces pages et vous prévenir par email lorsqu’une condition est détectée. Vous pouvez suivre un changement de texte, la présence d’un mot-clé ou décrire une condition en langage naturel pour une évaluation par IA. Le tableau de bord permet aussi de lancer une analyse ponctuelle et de consulter la dernière capture de la page.
Pourquoi un outil comme celui-ci ?
Des services de surveillance de pages existent déjà. Mais ils tournent chez un tiers, avec leurs limites d’abonnement, et voient passer vos URL comme vos adresses email. webpagecheck s’installe dans votre propre subscription Azure : vous gardez la main sur les données, les identités et le coût.
Quelques exemples d’usage :
- L’ouverture des inscriptions à un événement, une certification ou une formation.
- Le retour en stock d’un produit ou un changement de prix.
- La publication d’une offre d’emploi ou d’un appel à candidatures.
- La mise à jour de conditions générales, d’une documentation ou d’une page de statut.
- Une annonce attendue sur un blog ou une page produit.
Ce que fait l’application
Le tableau de bord regroupe les pages surveillées, leur mode, leur état, la dernière capture et la dernière alerte :

- Trois modes de détection : un changement de contenu, l’apparition ou la disparition d’un mot-clé, ou une condition en langage naturel évaluée par Azure OpenAI avec un score et un seuil réglable.
- La lecture de la page rendue : les modes mot-clé et IA lisent la page après exécution du JavaScript dans Chromium, comme le ferait votre navigateur.
- Une capture à chaque contrôle : visible dans le tableau de bord et jointe à l’email d’alerte.
- Des alertes email via Azure Communication Services, marquées URGENT et en priorité haute, avec des destinataires supplémentaires possibles par page.
- Scan et Check now : analyser une page sans rien envoyer, ou forcer un vrai contrôle. Chaque surveillance peut aussi être mise en pause, modifiée ou supprimée.
- Un mode test : les alertes sont simulées et consultables dans Alerts, sans envoyer d’email.
- Une sécurité de base : identité managée pour ACR et Azure OpenAI (aucune clé à gérer), mot de passe sur l’interface, URL publiques uniquement et données conservées dans Azure Files.
Dans cet article, on va déployer l’application sur Azure Container Apps à partir du script PowerShell du projet. Puis on configurera les notifications et une première surveillance, jusqu’au test de fonctionnement. L’IA reste optionnelle : les modes changement et mot-clé n’en ont pas besoin.
Pour vous guider plus facilement dans cet article, voici des liens rapides :
- 1. Comprendre les trois modes de surveillance
- 2. Les prérequis et les services Azure utilisés
- 3. Récupérer le projet et préparer le dossier
- 4. Préparer Azure CLI et la bonne subscription
- 5. Lancer le déploiement PowerShell
- 6. Ouvrir l’application et configurer l’accès
- 7. Configurer les notifications email
- 8. Créer et tester une première surveillance
- 9. Aller plus loin avec le mode IA
- 10. Comprendre les captures et le choix de sandbox
- 11. Les pièges à connaître avant de laisser tourner
- 12. Combien ça coûte ?
- 13. Conclusion
1. Comprendre les trois modes de surveillance
Concrètement, ça donne quoi ? Plutôt que de tout faire reposer sur l’IA, l’outil propose trois modes. Le bon choix dépend de ce que vous cherchez à détecter.
| Mode | Ce que l’outil vérifie | Comportement de l’alerte |
|---|---|---|
| Change | Une empreinte du texte extrait de la réponse HTML. | Le premier passage sert de référence. Les changements suivants déclenchent une alerte. |
| Keyword | La présence d’un mot-clé dans le texte de la page rendue par Chromium, sans distinction de casse. | Une alerte à l’apparition, puis à la disparition. Un mot-clé déjà présent au premier passage peut donc déclencher une alerte. |
| AI | Une condition décrite en langage naturel, évaluée par Azure OpenAI sur le texte de la page rendue. | Une alerte lorsque le score atteint le seuil. Une nouvelle alerte nécessite ensuite un passage sous le seuil, puis un nouveau franchissement. |
Exemple : pour détecter l’ouverture d’inscriptions, un mot-clé très précis peut suffire. Si la formulation varie, le mode IA permet d’exprimer une condition comme « Les inscriptions à cet événement sont ouvertes ». Son score reste une estimation du modèle, pas une garantie que l’événement a réellement eu lieu.
2. Les prérequis et les services Azure utilisés
Ce tutoriel utilise un poste Windows avec PowerShell et Azure CLI. Le script de déploiement protège son fichier temporaire de paramètres sensibles avec des ACL Windows : ne le lancez pas tel quel depuis un Cloud Shell Linux ou WSL.
- Une subscription Azure autorisant les services nécessaires et leur facturation.
- Les droits de créer un groupe de ressources, de déployer l’infrastructure et d’attribuer les rôles à l’identité managée.
- Azure CLI installé et un terminal PowerShell autorisant l’exécution du script selon votre politique d’entreprise.
- Si vous activez l’IA, un accès au modèle et un quota suffisants pour le déploiement Azure OpenAI choisi.
Microsoft.Authorization/roleAssignments/write. Il n’est pas nécessaire de donner des droits permanents excessifs au compte qui réalise le déploiement.L’application repose sur Python et Flask, avec Waitress pour servir l’interface. Playwright et Chromium réalisent les captures. Le script Bicep prépare les composants suivants :
| Composant | Rôle dans le projet |
|---|---|
| Azure Container Apps et son environnement | Exécuter le conteneur et exposer l’interface en HTTPS. |
| Azure Container Registry | Construire à distance et conserver l’image Docker. |
| Identité managée utilisateur | Récupérer l’image avec AcrPull et, si activé, appeler Azure OpenAI avec le rôle Cognitive Services OpenAI User. |
| Compte de stockage et partage Azure Files | Conserver la configuration et les captures sous /data, au-delà du cycle de vie du conteneur. |
| Log Analytics | Recevoir les journaux de l’application. |
| Azure OpenAI, optionnel | Évaluer les conditions en langage naturel. |
| Email Communication Service, domaine Azure et Communication Services, optionnels | Fournir le domaine expéditeur et envoyer les notifications. |
Pas besoin de Docker ni de Python sur le poste pour ce parcours de déploiement : le build se fait dans ACR et l’installation Python se déroule dans l’image. Il faut en revanche récupérer tous les fichiers du projet nécessaires au build.
3. Récupérer le projet et préparer le dossier
Ouvrez Visual Studio Code, puis récupérez la version du projet mise à disposition avec cet article :
https://github.com/jlou07/webpagecheck

Puis clonez le dans un dossier de travail. Dans les exemples, j’utilise C:\Lab\webpagecheck : adaptez ce chemin à votre poste :

À la racine, vous devez notamment retrouver deploy.ps1, Dockerfile, .dockerignore, requirements.txt, les modules Python, le dossier static et infra\main.bicep. Gardez les exemples sans secret : pas de fichier de configuration personnel, de captures privées ni d’identifiants de votre environnement dans le paquet partagé.
Set-Location 'C:\Lab\webpagecheck'
Get-ChildItem

4. Préparer Azure CLI et la bonne subscription
Installez Azure CLI avec la procédure Microsoft adaptée à votre poste, puis ouvrez un nouveau terminal. Une fois l’outil disponible, connectez-vous et sélectionnez explicitement la subscription cible.
az version
az login --use-device-code
az account list --output table
$subscriptionId = Read-Host 'ID de la subscription cible'
az account set --subscription $subscriptionId
az account show --query "{Subscription:name,Id:id}" --output table
az bicep version
az extension add --name containerapp --upgrade
Si Bicep n’est pas encore disponible, la CLI sait l’installer lorsqu’une commande en a besoin. La documentation Microsoft explique également son installation et sa mise à jour. Si votre poste ou votre subscription applique des restrictions, réglez-les avant le lancement plutôt que de contourner les politiques de sécurité.

az account show avant de continuer. Sur une capture destinée au blog, masquez l’identifiant de subscription et les informations de compte.5. Lancer le déploiement PowerShell
Choisissez un groupe de ressources dédié à ce lab et un préfixe court. Le préfixe doit comporter de trois à huit caractères, en lettres minuscules et chiffres. Les valeurs ci-dessous sont des exemples, pas les identifiants d’une instance existante.
$resourceGroup = 'rg-webpagecheck-demo'
$namePrefix = 'wpcdemo'
$appName = "${namePrefix}-web"
$deployParameters = @{
ResourceGroup = $resourceGroup
NamePrefix = $namePrefix
Location = 'francecentral'
OpenAiLocation = 'swedencentral'
ChromiumSandbox = $false
}
# Redéploiement uniquement : réutiliser le mot de passe existant
if (az containerapp show -g $resourceGroup -n $appName --query name -o tsv 2>$null) {
$deployParameters.UiPassword = az containerapp secret list -g $resourceGroup -n $appName --show-values `
--query "[?name=='ui-password'].value | [0]" -o tsv
}
.\deploy.ps1 @deployParameters
Au premier déploiement, l’application n’existe pas encore : le script génère alors un mot de passe initial. Lors d’un redéploiement, le bloc if réutilise le mot de passe existant. Le paramètre ChromiumSandbox = $false est nécessaire pour les captures sur Container Apps : il est expliqué en section 10.

Les ressources Azure commencent à apparaître :

Par défaut, l’email et Azure OpenAI sont activés. Le modèle configuré dans le Bicep du projet est gpt-4.1-mini, version 2025-04-14, en déploiement Global Standard. Vérifiez sa disponibilité, son cycle de vie et votre capacité à le déployer avant de lancer le script. Les régions d’exemple ne constituent pas une garantie de disponibilité pour votre subscription.
Pour commencer sans IA, ajoutez cette ligne avant l’appel du script :
$deployParameters.DeployOpenAi = $false
Cette option conserve les modes changement et mot-clé. L’option DeployEmail = $false existe également, mais elle retire l’envoi d’emails attendu dans ce tutoriel. Choisissez vos options avant l’exécution, ne lancez pas chaque variante à la suite.
Le script déroule quatre opérations :
- Créer le groupe de ressources.
- Déployer l’infrastructure avec Bicep, sans l’application dans cette première passe.
- Construire l’image dans Azure Container Registry.
- Déployer la Container App avec l’image qui vient d’être construite.
À la fin, le script affiche l’URL de l’interface, l’adresse expéditrice si l’email est activé et l’endpoint OpenAI si l’IA est activée :

Il n’affiche pas automatiquement le mot de passe initial. Vous pouvez le retrouver ici côté portail Azure :

L’URL est aussi disponible juste là:

UiPassword, chaque exécution génère un nouveau mot de passe initial et remplace ce secret. Ne le relancez pas au hasard pour corriger un réglage. Un identifiant déjà enregistré dans l’interface reste, lui, prioritaire sur ce mot de passe initial.6. Ouvrir l’application et configurer l’accès
Ouvrez la page de l’application, puis saisissez les identifiants :

Vous voilà dans l’application, rien de plus !
7. Configurer les notifications email
Dans le panneau Configuration, renseignez l’adresse expéditrice indiquée à la fin du déploiement et une adresse de destination que vous contrôlez. Pour le premier test, un seul destinataire suffit :

- Renseignez Sender address avec l’expéditeur fourni par le domaine Azure Communication Services. Une adresse arbitraire de votre messagerie ne convient pas.
- Renseignez Recipient addresses. Plusieurs adresses peuvent être séparées par des virgules.
- Enregistrez les paramètres.
- Vérifiez que l’envoi est actif et utilisez Send test notification pour recevoir un véritable email.

En mode test, les alertes sont conservées comme simulées dans l’interface, mais aucun email ne part. Le test de notification est lui aussi simulé lorsque l’envoi est désactivé. Un statut simulé ne prouve donc pas que votre messagerie a reçu quelque chose.
Si vous utilisez votre propre domaine, c’est parfaitement possible. Voici un domaine déjà utilisé dans Microsoft 365 :

Et dont la zone DNS est gérée sous Azure :

Depuis le portail Azure, sur les ressources créées, commencez par le vérifier dans le service Email :

Créez si besoin un MailFrom :

Puis liez-le à la ressource Communication Services :

Reconfigurez puis refaites un test d’envoi :

Contrôlez la bonne réception du test :

L’option CustomEmailDomain du script doit être conservée lors de ses prochaines exécutions : sinon, le déploiement revient au seul lien avec le domaine Azure.
8. Créer et tester une première surveillance
On commence avec un cas simple et sans IA. Ajoutez une page avec les valeurs suivantes :
| Champ | Valeur d’exemple |
|---|---|
| Name | Test Example Domain |
| URL | https://example.com/ |
| Mode | Keyword |
| Keyword | servicio |
| Interval | 60 minutes |
| Extra email addresses | Laisser vide pour le premier test. |

Enregistrez la page, puis attendez quelques secondes le résultat de l’analyse automatique :

Quelques secondes plus tard, le mail d’alerte arrive également :

Modifiez le test existant en remplaçant le mot par un autre qui n’existe pas, sauvegardez :

Quelques secondes plus tard, constatez le résultat de la seconde analyse automatique :

L’icône Scan affiche l’analyse et le contenu de l’email qui serait préparé. Le Scan ne modifie pas l’état de référence de la surveillance et n’envoie pas d’email :

L’icône Check now est différente : elle réalise une vraie vérification, met à jour l’état et peut déclencher une alerte si la condition le justifie :

Le moment de vérité : une fois l’analyse validée, réactivez l’envoi et provoquez une transition contrôlée. Vérifiez la réception de l’email, puis son statut dans Alerts. Une fois ce parcours validé, choisissez un intervalle raisonnable pour vos vraies surveillances.
9. Aller plus loin avec le mode IA
Si Azure OpenAI a été déployé, le badge de l’interface indique que l’IA est active. Vous pouvez créer une surveillance en mode AI, décrire votre condition et fixer le seuil de déclenchement. La valeur par défaut est 70 %.

Sur une page d’inscription publique, une condition utile serait par exemple : « Les inscriptions sont ouvertes et un lien permet de s’inscrire maintenant, pas seulement de consulter la date d’ouverture. » Soyez précis sur ce qui distingue le résultat attendu d’une simple annonce.
Le modèle reçoit la condition et le texte extrait de la page, limité aux 12 000 premiers caractères. Il retourne un score et une explication. L’application utilise son identité managée pour appeler Azure OpenAI dans ce déploiement : vous n’avez pas de clé OpenAI à coller dans le navigateur.

Changez le test pour vérifier le comportement :

L’IA arrive bien à faire la distinction avec ce changement de test :

Et l’email d’alerte arrive bien :

10. Comprendre les captures et le choix de sandbox
Chaque véritable contrôle essaie de prendre une capture, même sans alerte à envoyer. La colonne Last capture donne accès à cette image. Seule la dernière capture de contrôle est conservée par page, dans le stockage persistant. Le Scan dispose de sa propre capture et ne remplace pas celle du dernier contrôle :

Si une capture échoue, l’ancienne image est retirée plutôt que présentée comme récente. La collecte du texte et les alertes peuvent continuer sans image. Consultez les journaux pour distinguer un échec de navigation, un blocage du site et un problème de lancement de Chromium.
La sandbox Chromium est activée par défaut dans le code et dans le Bicep. Sur Azure Container Apps, elle ne peut pas démarrer : le conteneur n’a pas accès aux namespaces utilisateur et Chromium s’arrête avec l’erreur No usable sandbox!. C’est pourquoi le déploiement de la section 5 passe ChromiumSandbox = $false. Il n’existe aucun basculement automatique vers un navigateur sans sandbox.
Si vous avez déployé sans ce paramètre et que les journaux affichent cette erreur, la commande suivante change uniquement cette variable d’environnement et crée une nouvelle révision, sans relancer tout le déploiement :
az containerapp update `
--resource-group $resourceGroup `
--name $appName `
--set-env-vars CHROMIUM_SANDBOX=false `
--output none
Ce choix ne désactive ni le proxy public uniquement, ni les vérifications TLS, ni l’utilisateur non-root du conteneur. Si vous rejouez plus tard le déploiement complet, l’option PowerShell correspondante est -ChromiumSandbox:$false. Sans cette option, le modèle Bicep réactive la sandbox. Ne réduisez pas l’isolation simplement pour faire disparaître un message d’erreur non diagnostiqué.
11. Les pièges à connaître avant de laisser tourner
Une capture visible n’est pas la preuve que le texte surveillé est complet
Les modes mot-clé et IA lisent le texte de la page rendue par Chromium, après exécution du JavaScript : un texte ajouté dynamiquement, comme les traductions de la page example.com, est donc bien détecté. Si Chromium échoue, l’application se rabat sur le HTML brut de la collecte HTTP, qui peut ne pas contenir ce texte. Le mode changement compare toujours le HTML brut, pour éviter les fausses alertes dues aux éléments dynamiques. Les pages avec authentification, CAPTCHA ou protection anti-bot peuvent également ne pas convenir. Testez votre cible avec le Scan avant de lui faire confiance.
Uniquement des destinations publiques
Les URL privées, locales et de métadonnées cloud sont refusées. Les redirections et les ressources chargées par Chromium passent par un proxy temporaire authentifié qui vérifie les adresses et se connecte à l’adresse IP contrôlée. Ce n’est donc pas un outil pour surveiller votre intranet. Respectez aussi les conditions d’utilisation des sites surveillés et évitez les fréquences agressives.
Une seule réplique pour cette version
La persistance repose sur un fichier JSON et des images dans Azure Files. Le déploiement fixe une réplique minimum et maximum. Ne montez pas simplement le nombre de répliques pour « faire plus robuste » : cette version ne dispose pas d’un ordonnanceur distribué ni d’une coordination multi-instance.
Prévoir une vraie frontière de sécurité
L’interface utilise une authentification Basic sur HTTPS. Cela ne fournit pas, à lui seul, un SSO Entra ID, du MFA ou une gestion multi-utilisateur. Pour une exposition plus large qu’un usage personnel ou de lab, étudiez un contrôle d’accès en amont, des restrictions réseau adaptées et une protection contre les tentatives répétées de connexion.
Les dépendances Python sont verrouillées avec des hachages et l’image s’exécute avec un utilisateur non-root. Des tests couvrent notamment les URL privées, les redirections, le DNS rebinding, la validation TLS et le traitement du mot de passe au déploiement. Ces protections ne constituent pas une certification de sécurité : maintenez aussi l’image de base, les paquets système et Chromium à jour, et réalisez un audit de vulnérabilités avant une exposition sensible.
12. Combien ça coûte ?
Voici une estimation pour un mois complet avec les paramètres par défaut du script : une page ou quelques pages contrôlées toutes les heures, Container Apps en France Central et Azure OpenAI en Sweden Central. Les prix sont les tarifs publics en dollars, relevés en octobre 2026, hors remise et hors taxes.
| Composant | Base de facturation | Estimation mensuelle |
|---|---|---|
| Container Apps (0,5 vCPU, 1 Gio, une réplique permanente) | vCPU actif 0,000024 $/s, inactif 0,000003 $/s. Mémoire 0,000003 $/Gio-s. Offre gratuite mensuelle de 180 000 vCPU-s et 360 000 Gio-s par subscription. | ≈ 10 $ si la réplique est surtout inactive, jusqu’à ≈ 34 $ si elle est active en permanence. |
| Container Registry Basic | 0,1666 $ par jour. | ≈ 5 $ |
| Azure Files (Standard LRS, quota 1 Gio) | 0,075 $ par Go et par mois, plus les transactions. | < 0,50 $ |
| Log Analytics | 5 Go gratuits par mois, puis 2,76 $ par Go. | ≈ 0 $ pour ce lab |
| Azure OpenAI gpt-4.1-mini (Global Standard) | 0,40 $ par million de tokens en entrée, 1,60 $ en sortie. | ≈ 0,15 à 1,20 $ pour une page en mode IA contrôlée toutes les heures |
| Communication Services Email | 0,00025 $ par email, plus 0,00012 $ par Mo. | Quelques centimes |
| Total | ≈ 15 à 16 $ par mois (environ 14 €) pour un usage léger |
La facture est dominée par deux postes fixes : la réplique Container Apps qui tourne en permanence et le registre ACR. Les appels IA, le stockage et les emails restent marginaux à cette échelle.
Ce que j’ai réellement payé
Sur mon lab, du 16 au 21 octobre 2026, soit environ 5 jours, Cost Management affiche environ 1,17 € pour le groupe de ressources : 0,72 € pour ACR, 0,30 € pour Container Apps, 0,11 € pour Azure OpenAI, 0,03 € pour le stockage, 0,01 € pour l’email et 0 € pour Log Analytics.

Comment réduire la facture
- Désactivez l’IA si les modes changement et mot-clé suffisent :
$deployParameters.DeployOpenAi = $false. - Choisissez des intervalles raisonnables : chaque contrôle lance Chromium et, en mode IA, un appel au modèle.
- Ne comptez pas sur le scale to zero : le planificateur tourne dans le processus de l’application, la réplique minimum est donc fixée à 1 dans cette version.
- Créez un budget Azure avec une alerte sur le groupe de ressources avant de laisser tourner le lab.
- À la fin du lab, supprimez tout le groupe de ressources :
az group delete --name $resourceGroup --yes --no-wait. La ressource Azure OpenAI passe alors en suppression réversible : purgez-la si vous voulez réutiliser le même nom.
Pour votre propre estimation, utilisez la calculatrice de prix Azure et les pages de tarifs de Container Apps, Container Registry et Azure OpenAI. Pour le budget, suivez le tutoriel Créer et gérer des budgets, Microsoft Learn.
13. Conclusion
Voilà, du déploiement PowerShell à la première surveillance, vous avez de quoi automatiser une vérification que vous faisiez jusque-là à la main. Le plus intéressant n’est pas forcément d’ajouter de l’IA partout : un mot-clé bien choisi ou un simple suivi de changement peut déjà répondre au besoin.
Les pièges à retenir : choisir la bonne subscription, distinguer Scan et Check now, surveiller les quotas email et ne pas confondre une capture réussie avec une analyse complète de la page. Pour les captures, le compromis de sandbox doit rester un choix explicite, pas un détail caché.
Foncez tester en lab, avec une page publique et une boîte de réception que vous contrôlez. Validez le parcours complet avant de laisser tourner vos vraies surveillances.
