![]() |
Ti è mai capitato di aggiornare ossessivamente una pagina web in attesa che un prodotto torni disponibile, o che vengano pubblicati gli esiti di un esame?
Oppure hai mai dovuto monitorare un sito per essere sicuro che fosse up&running (per intervenire tempestivamente in caso di problemi)?
Fare refresh manuale ogni giorno (o ogni ora!) è una perdita di tempo. Oggi vedremo come costruire un Monitor di Contenuti Web in Python: uno script leggero che controlla periodicamente uno specifico tag HTML su un sito e ti avvisa non appena rileva un cambiamento.
🛠️ Gli strumenti del mestiere
Per questo progetto usiamo due delle librerie più famose e amate dell'ecosistema Python:
requests: La libreria standard de facto per effettuare richieste HTTP. Ci servirà per scaricare il codice HTML della pagina web target.beautifulsoup4(BS4): Un fantastico parser HTML/XML che ci permette di navigare nella struttura della pagina ed estrarre esattamente il contenuto del tag che ci interessa.
Se non le hai ancora installate, apri il terminale e lancia:
pip install requests beautifulsoup4
💡 Come funziona l'algoritmo?
Il funzionamento del nostro monitor si basa su un ciclo continuo molto semplice:
- Download: Effettuiamo una richiesta GET all'URL target.
- Parsing: Analizziamo l'HTML con BeautifulSoup per trovare il tag desiderato (es.
<div id="stock-status">). - Confronto: Verifichiamo se il valore estratto è diverso da quello memorizzato durante il controllo precedente.
- Notifica: Se c'è stato un cambio, inviamo un avviso nel terminale (o via email/Telegram).
- Attesa: Mettiamo lo script in "pausa" con un conto alla rovescia prima del controllo successivo.
💻 Il Codice Finale
Ecco lo script completo. Puoi salvarlo in un file chiamato web_monitor.py.
import time
import sys
from datetime import datetime
import requests
from bs4 import BeautifulSoup
# ==========================================
# CONFIGURAZIONE DEL MONITOR
# ==========================================
URL_TARGET = "https://www.example.com"
TAG_NAME = "span"
TAG_ATTRS = {"id": "logo"} # Es: {"class": "in-stock"} o {"id": "status"}
CHECK_INTERVAL = 300 # Intervallo in secondi (es. 300 sec = 5 minuti)
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}
def get_target_content(url, tag_name, attrs):
"""
Effettua la richiesta HTTP ed estrae il testo dal tag specificato.
"""
try:
response = requests.get(url, headers=HEADERS, timeout=10)
response.raise_for_status()
soup = BeautifulSoup(response.text, "html.parser")
element = soup.find(tag_name, attrs=attrs)
if element:
return element.get_text(strip=True)
else:
print(f"\n⚠️ [{datetime.now().strftime('%H:%M:%S')}] Tag non trovato nella pagina.")
return None
except requests.RequestException as e:
print(f"\n❌ [{datetime.now().strftime('%H:%M:%S')}] Errore durante la richiesta HTTP: {e}")
return None
def countdown(seconds):
"""
Mostra un conto alla rovescia in formato MM:SS sulla stessa riga di terminale.
"""
for remaining in range(seconds, 0, -1):
mins, secs = divmod(remaining, 60)
timer = f"{mins:02d}:{secs:02d}"
# \r sovrascrive la riga corrente nel terminale
sys.stdout.write(f"\r⏳ In attesa di un nuovo check tra {timer} ")
sys.stdout.flush()
time.sleep(1)
# Pulisce la riga prima dell'output successivo
sys.stdout.write("\r" + " " * 50 + "\r")
sys.stdout.flush()
def start_monitoring():
"""
Ciclo principale di monitoraggio.
"""
print(f"🚀 Monitor avviato per: {URL_TARGET}")
print(f"⏱️ Intervallo di controllo: {CHECK_INTERVAL} secondi\n")
# Primo controllo per salvare lo stato iniziale
last_state = get_target_content(URL_TARGET, TAG_NAME, TAG_ATTRS)
if last_state is None:
print("Impossibile avviare il monitor: elemento iniziale non trovato o errore HTTP.")
return
print(f"📌 Stato iniziale registrato: '{last_state}'\n")
try:
while True:
# Avvia il conto alla rovescia interattivo
countdown(CHECK_INTERVAL)
current_time = datetime.now().strftime('%d/%m/%Y %H:%M:%S')
current_state = get_target_content(URL_TARGET, TAG_NAME, TAG_ATTRS)
if current_state is None:
continue
# Verifichiamo se c'è stato un cambio di stato
if current_state != last_state:
print("=" * 50)
print(f"🔔 NOTIFICA! CAMBIAMENTO RILEVATO [{current_time}]")
print(f"🔴 Stato precedente: {last_state}")
print(f"🟢 Nuovo stato: {current_state}")
print("=" * 50 + "\n")
last_state = current_state
else:
print(f"✅ [{current_time}] Nessun cambio. Stato attuale: '{current_state}'")
except KeyboardInterrupt:
print("\n🛑 Monitor arrestato dall'utente.")
if __name__ == "__main__":
start_monitoring()
🔍 Come personalizzarlo per il tuo sito target
Per adattare questo script alla pagina che ti interessa, segui questi 3 passaggi:
- Apri la pagina su Chrome o Firefox, fai tasto destro sul testo da monitorare e seleziona Ispeziona.
- Guarda l'HTML evidenziato nel pannello sviluppatori:
- Identifica il tipo di tag (es.
div,span,p,h1). - Cerca una proprietà univoca, come un
ido unaclass.
- Identifica il tipo di tag (es.
- Aggiorna le variabili
TAG_NAMEeTAG_ATTRSnel codice Python in base a ciò che hai identificato al punto precedente:TAG_NAME = "div" TAG_ATTRS = {"class": "badge-disponibilita"}
🎯 Prossimi passi e miglioramenti
Questo script è una solida base di partenza. Se vuoi spingerlo oltre, ecco alcune idee di upgrade:
- Notifiche Push/Telegram: Invece di stampare solo su terminale, usa le API di Telegram (
python-telegram-bot) per farti mandare un messaggio sullo smartphone. - Esecuzione in Cloud: Carica lo script su una VPS o su piattaforme come PythonAnywhere per farlo girare H24 senza tenere acceso il PC di casa.
- Supporto a JavaScript: Se il sito carica i dati tramite AJAX/React,
requestspotrebbe non vedere il contenuto finale. In quel caso, valuta l'uso di Playwright o Selenium.
Techelopment ha già pensato a tutto 😊
👉 Il programma completo (site_monitoring.py) mostrato nell’articolo è disponibile su GitHub, così da poter essere scaricato, eseguito e adattato facilmente alle proprie esigenze.
Follow me #techelopment
Official site: www.techelopment.it
facebook: Techelopment
instagram: @techelopment
X: techelopment
Bluesky: @techelopment
telegram: @techelopment_channel
whatsapp: Techelopment
youtube: @techelopment
