Come evitare i captcha durante lo scraping (senza violare le regole)
La maggior parte dei captcha durante lo scraping è una reazione a traffico che sembra automatizzato. Il modo meno costoso per gestirli è smettere di scatenarli. Significa cercare prima una fonte di dati legittima, verificare cosa consentono le regole del sito, inviare meno richieste e più lente, e non scaricare due volte la stessa pagina. Risolvere un captcha è il ripiego per i casi che non puoi evitare, non il piano.
Cerca prima un'API o un feed ufficiali
Molti siti sottoposti a scraping offrono già un modo per ottenere gli stessi dati senza captcha: un'API pubblica, un export dei dati, un feed RSS o sitemap, oppure un programma per partner. Una fonte ufficiale è più affidabile, cambia meno senza preavviso e dà al proprietario del sito voce in capitolo sull'uso che ne fai. Cerca:
- una sezione per sviluppatori o API nel footer del sito,
sitemap.xmlper l'elenco delle pagine,- link RSS o Atom nel
<head>della pagina, - una pagina "data" o "download" per gli export in blocco.
Se una di queste copre la tua esigenza, usala. Eviterai la maggior parte dei captcha non richiedendo affatto l'HTML.
Rispetta robots.txt e il ritmo che chiede
robots.txt indica quali percorsi i client automatici possono richiedere e, a volte, quanto attendere tra una richiesta e l'altra. La libreria standard di Python può leggerlo per te:
import time
from urllib.robotparser import RobotFileParser
import requests
USER_AGENT = "ExampleBot/1.0 (+https://example.com/bot)"
parser = RobotFileParser()
parser.set_url("https://example.com/robots.txt")
parser.read()
delay = parser.crawl_delay(USER_AGENT) or 5 # ripiego su 5 secondi, un valore prudente
urls = [
"https://example.com/products?page=1",
"https://example.com/products?page=2",
]
last_request = 0.0
for url in urls:
if not parser.can_fetch(USER_AGENT, url):
print("skipped by robots.txt:", url)
continue
wait = delay - (time.monotonic() - last_request)
if wait > 0:
time.sleep(wait)
resp = requests.get(url, headers={"User-Agent": USER_AGENT}, timeout=30)
last_request = time.monotonic()
print(url, resp.status_code)
Se robots.txt vieta un percorso, la risposta onesta è lasciarlo stare o chiedere al proprietario. Aggirarlo con un browser non cambia ciò che il sito ha chiesto.
Rallenta e distribuisci le richieste
Un ritmo costante e moderato raramente scatena una sfida, mentre una raffica quasi sempre lo fa. Alcune abitudini fanno una grande differenza:
- Scegli un ritmo di richieste per sito e mantienilo, invece di andare alla massima velocità.
- Aggiungi un jitter casuale così i tempi non sono perfettamente regolari.
- Fermati e attendi un po' quando vedi un 429 o una pagina captcha.
- Esegui i job nelle ore di minor traffico se il carico del sito è un problema.
Usa la cache ed evita di riscaricare
Ogni richiesta che non fai è una richiesta che il sito non deve gestire. Salva le pagine che scarichi con la loro data e un hash del corpo, e riscaricale solo quando il contenuto è probabilmente cambiato. Le richieste condizionali con gli header If-Modified-Since o ETag permettono al server di rispondere in modo economico "non modificato", quando le supporta.
Riusa le sessioni, invia header ordinari
Una sessione che mantiene i cookie tra una richiesta e l'altra si comporta più come un visitatore che come uno script che riparte da zero ogni volta. Usa requests.Session() per ogni sito e invia uno User-Agent chiaro e onesto, che indichi il tuo bot e un contatto. Non fingere di essere un browser per aggirare una regola. Se un sito richiede JavaScript per mostrare il contenuto, usa uno strumento browser per quelle pagine, e mantieni gli stessi limiti di ritmo.
Quando compare comunque un captcha
Alcuni siti mostreranno un captcha qualunque sia il tuo comportamento attento. Rilevalo nel codice e ferma quel job invece di martellare la pagina. Il rilevamento e la risoluzione facoltativa per PopularCaptcha sono trattati in captcha nello scraping: perché compaiono.
Pianifica il crawl prima di iniziare
Un crawl che scarica tutto ogni giorno è il modo più semplice per scatenare un captcha. Pianifica il lavoro prima:
- Dai priorità. Decidi quali pagine cambiano spesso e quali raramente. Esegui il crawl delle prime spesso e delle altre raramente.
- Usa le date della sitemap. Molte sitemap includono un valore
lastmod. Salta gli URL che non sono cambiati dalla tua ultima visita. - Crawl incrementale. Salva l'ultimo download riuscito per ogni URL, e riprendi da lì invece di ripartire dalla prima pagina dopo un errore.
- Distribuisci il carico. Dividi una lista grande in batch e falli girare durante la giornata, non tutti insieme.
Un piano del genere riduce il numero di richieste, che è la leva più importante a tua disposizione.
Scrivi il piano come un breve file di configurazione o una tabella: i siti, le sezioni, l'intervallo di aggiornamento e il budget giornaliero di richieste per ciascuno. Quando il budget è esaurito, il job si ferma fino alla finestra successiva. Trattare il budget come un limite rigido, e non come una linea guida, è ciò che impedisce a un crawler di scivolare nel pattern di traffico che scatena i captcha. Rivedi il budget ogni poche settimane, perché un sito che cresce può anche far crescere il suo traffico, e ciò che era accettabile il trimestre scorso potrebbe non esserlo più.
Scraping responsabile
- Controlla
robots.txte i termini di servizio prima di iniziare, e rispetta quello che dicono. - Mantieni basso il ritmo delle richieste e fermati quando il sito segnala di essere in difficoltà.
- Non raccogliere dati personali per cui non hai una ragione, ed eliminali quando non ti servono più.
- Non ripubblicare in blocco contenuti protetti da copyright. Usa i dati per analisi, confronti o per un tuo prodotto, e cita la fonte dove è appropriato.
- Contatta il proprietario del sito se ti servono volumi più grandi. Potrebbe offrirti un feed.