Pratiche di scraping responsabile
Rispetto di robots.txt, header user agent, ritardi tra le richieste e caching
Pratiche di scraping responsabile è una lezione AI Agents gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Agents, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Agents include 4 lezioni in totale.
Perché è importante fare scraping in modo rispettoso
Lo web scraping può sovraccaricare i server, violare i termini di servizio e causare il blocco dell'indirizzo IP del Suo agente. Chi esegue scraping in modo responsabile rispetta i limiti di frequenza, si identifica e osserva le regole pubblicate dai siti web.
Questa lezione illustra gli strumenti e le tecniche per fare scraping in modo etico e sostenibile.
Verificare robots.txt
Ogni sito web può pubblicare un file robots.txt che specifica quali percorsi gli agenti automatizzati possono o non possono visitare. La libreria standard di Python include urllib.robotparser per analizzare questo file.
Verifichi sempre robots.txt prima di eseguire lo scraping di un sito.
import urllib.robotparser
rp = urllib.robotparser.RobotFileParser()
rp.set_url('https://example.com/robots.txt')
rp.read()
# Check if our bot can fetch a specific path
can_fetch = rp.can_fetch('MyAgent/1.0', 'https://example.com/public-data')
print(f'Can fetch: {can_fetch}') # True or False
cannot_fetch = rp.can_fetch('*', 'https://example.com/private/admin')
print(f'Admin allowed: {cannot_fetch}') # Often FalseImpostare uno User-Agent descrittivo
L'header HTTP User-Agent identifica chi sta effettuando una richiesta. Uno User-Agent trasparente consente agli amministratori del sito di sapere cos'è il Suo bot e come contattarLa in caso di problemi. Camuffarsi da browser per eludere i blocchi solleva questioni etiche.
import httpx
headers = {
# Honest, descriptive User-Agent
'User-Agent': 'MyResearchBot/1.0 (contact: me@example.com; purpose: academic research)'
}
response = httpx.get(
'https://example.com/data',
headers=headers,
timeout=10.0
)
print(response.status_code)Limitare la frequenza con time.sleep()
L'invio di centinaia di richieste al secondo può sovraccaricare un server e viene spesso considerato un attacco di negazione del servizio. Aggiunga ritardi tra le richieste usando time.sleep(). Usi random.uniform() per rendere il ritardo meno meccanico e più simile a quello di un utente.
import time
import random
import httpx
urls = [
'https://example.com/page/1',
'https://example.com/page/2',
'https://example.com/page/3'
]
for url in urls:
response = httpx.get(url, timeout=10.0)
print(f'Fetched {url}: {response.status_code}')
# Wait between 1 and 3 seconds before the next request
delay = random.uniform(1, 3)
print(f'Sleeping {delay:.1f}s...')
time.sleep(delay)Rispettare gli header Retry-After
Quando un server risponde con 429 Too Many Requests, spesso include un header Retry-After che specifica quanti secondi attendere. Il Suo agente dovrebbe leggerlo e rispettarlo invece di riprovare immediatamente.
import time
import httpx
def fetch_with_retry(url: str) -> httpx.Response:
while True:
response = httpx.get(url, timeout=10.0)
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 5))
print(f'Rate limited. Waiting {retry_after}s...')
time.sleep(retry_after)
continue # retry
response.raise_for_status()
return responseMemorizzare nella cache le risposte per evitare richieste ripetute
requests-cache memorizza automaticamente nella cache le risposte HTTP su disco. Se il Suo agente deve recuperare più volte lo stesso URL, ad esempio durante lo sviluppo o nuove esecuzioni, le risposte memorizzate nella cache vengono restituite immediatamente senza contattare il server.
# pip install requests-cache
import requests_cache
# Install the cache globally — cached responses expire after 1 hour
requests_cache.install_cache(
'agent_cache',
backend='sqlite',
expire_after=3600 # seconds
)
import requests
# First call: fetches from network and caches
response = requests.get('https://api.example.com/data')
print(response.from_cache) # False
# Second call: returns cached result instantly
response2 = requests.get('https://api.example.com/data')
print(response2.from_cache) # TrueMemorizzazione manuale nella cache basata su file con httpx
Se preferisce non usare requests-cache, una semplice cache basata su file funziona bene. Memorizzi le risposte come file JSON indicizzati dall'hash dell'URL e le ricarichi se il file è sufficientemente recente.
import hashlib
import json
import os
import time
import httpx
CACHE_DIR = '/tmp/agent_cache'
os.makedirs(CACHE_DIR, exist_ok=True)
def cached_get(url: str, ttl_seconds: int = 3600) -> dict:
key = hashlib.md5(url.encode()).hexdigest()
cache_file = os.path.join(CACHE_DIR, key + '.json')
if os.path.exists(cache_file):
age = time.time() - os.path.getmtime(cache_file)
if age < ttl_seconds:
with open(cache_file) as f:
return json.load(f)
response = httpx.get(url, timeout=10.0)
response.raise_for_status()
data = response.json()
with open(cache_file, 'w') as f:
json.dump(data, f)
return dataLeggere i Termini di servizio
Prima di eseguire lo scraping di un sito, ne legga i Termini di servizio. Molti vietano esplicitamente l'accesso automatizzato o l'uso commerciale dei propri dati. La violazione dei ToS può comportare azioni legali, non soltanto il blocco dell'indirizzo IP.
Se esiste un'API ufficiale, la preferisca sempre allo scraping dell'HTML: è più veloce, più stabile e comporta meno rischi legali.
Backoff esponenziale in caso di errori
Quando una richiesta non va a buon fine, non riprovi immediatamente. Usi un backoff esponenziale: attenda 1 s, poi 2 s, poi 4 s e così via. In questo modo evita di sovraccaricare un server in difficoltà; è una pratica professionale per gli agenti in produzione.
import time
import httpx
def fetch_with_backoff(url: str, max_retries: int = 4) -> dict:
for attempt in range(max_retries):
try:
response = httpx.get(url, timeout=10.0)
response.raise_for_status()
return response.json()
except (httpx.HTTPStatusError, httpx.RequestError) as e:
if attempt == max_retries - 1:
raise
wait = 2 ** attempt # 1, 2, 4, 8 seconds
print(f'Attempt {attempt+1} failed: {e}. Retrying in {wait}s...')
time.sleep(wait)
return {}Eseguire lo scraping solo dei dati necessari
Riduca il carico sul server recuperando solo ciò di cui il Suo agente ha effettivamente bisogno. Eviti di scaricare pagine intere quando un endpoint API più piccolo restituisce gli stessi dati. Usi richieste HEAD per verificare se una risorsa è cambiata prima di recuperare l'intero corpo della risposta.
import httpx
def has_page_changed(url: str, last_etag: str = None) -> bool:
headers = {}
if last_etag:
headers['If-None-Match'] = last_etag
response = httpx.head(url, headers=headers, timeout=5.0)
if response.status_code == 304: # Not Modified
return False
new_etag = response.headers.get('ETag')
print(f'New ETag: {new_etag}')
return TrueRiepilogo delle regole per uno scraping rispettoso
Una rapida lista di controllo prima che il Suo agente esegua lo scraping di un sito:
- Verifichi
robots.txte rispetti le regole di disallow - Imposti uno
User-Agenttrasparente e descrittivo - Aggiunga ritardi casuali tra le richieste (
time.sleep(random.uniform(1,3))) - Rispetti gli header
Retry-Afternelle risposte 429 - Memorizzi le risposte nella cache per evitare richieste ridondanti
- Legga i Termini di servizio del sito
- Preferisca le API ufficiali allo scraping dell'HTML quando disponibili
Verifica delle conoscenze: scraping rispettoso
Verifichi la Sua comprensione delle pratiche di scraping etiche e rispettose.
Riepilogo: pratiche di scraping rispettoso
Ora dispone di un kit completo di strumenti per eseguire lo scraping in modo responsabile:
robotparserper verificare a quali risorse è consentito accedere- Header
User-Agentdescrittivi che identificano il Suo bot time.sleep(random.uniform(1,3))tra le richiesterequests-cacheo una cache manuale per evitare recuperi duplicati- Backoff esponenziale per la gestione degli errori
- Consapevolezza degli aspetti legali: verifichi sempre i ToS
Fare scraping in modo responsabile contribuisce a un web più sano e consente ai Suoi agenti di funzionare senza essere bloccati.
Domande Frequenti
La lezione «Pratiche di scraping responsabile» è gratuita?
Sì — il testo completo di «Pratiche di scraping responsabile» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Agents, passa a CoddyKit PRO. Il corso AI Agents include 4 lezioni in totale.
Cosa imparerò in «Pratiche di scraping responsabile»?
Rispetto di robots.txt, header user agent, ritardi tra le richieste e caching Eserciti AI Agents con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare AI Agents?
Non è richiesta alcuna esperienza precedente. AI Agents su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Pratiche di scraping responsabile»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione AI Agents?
Sì. Ogni lezione AI Agents include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Client HTTP per agenti: httpx e requests
- Parsing dell’HTML con BeautifulSoup
- Gestione della paginazione e dei contenuti dinamici
- Pratiche di scraping responsabile