requests di Python restituisce spesso una pagina quasi vuota: recupera l’HTML grezzo, ma non esegue il JavaScript che lo popolerebbe con i dati realmente desiderati.
Esistono tre approcci per risolvere il problema e quello giusto dipende da come è costruito il sito. Quando applicabile, vince l’approccio meno costoso: verificali quindi nell’ordine seguente.
Approccio 1: renderizzare la pagina in un browser reale
La soluzione universale consiste nell’eseguire un motore browser reale che elabori JavaScript esattamente come il browser di un utente. La pagina si carica, gli script vengono eseguiti, partono le chiamate API e il contenuto viene renderizzato; soltanto allora il web scraper estrae i dati dal DOM completo. Questo metodo funziona con qualsiasi sito renderizzato tramite JavaScript, ma è più costoso: per ogni pagina si avvia un’istanza browser che consuma memoria e CPU reali. La scelta del motore browser è una questione a sé: librerie diverse (Puppeteer, Playwright, Selenium), API cloud diverse e diversi compromessi tra modalità headed e headless. La panoramica completa è disponibile in Il panorama dei runtime browser, mentre la decisione tra browser headed e headless più importante per lo scraping è trattata in Browser headed e headless a confronto. Il sovraccarico del runtime conta su larga scala, perciò un motore specializzato costa molto meno per pagina rispetto a un browser standard.Approccio 2: intercettare l’API sottostante
Le pagine renderizzate tramite JavaScript non creano i contenuti dal nulla: li recuperano da API back-end mediante richieste XHR ofetch. Se riesci a individuare questi endpoint, puoi chiamarli direttamente e ottenere JSON pulito e strutturato senza renderizzare alcun browser. È un metodo più veloce, leggero e affidabile del rendering dell’intera pagina: non occorre attendere il DOM, non vi sono selettori che si rompono quando cambia il layout e i dati arrivano già analizzati.
Il limite è che queste API possono non essere documentate, richiedere autenticazione o applicare limiti di frequenza, e possono cambiare senza preavviso. Il flusso di lavoro è quindi il seguente: apri la pagina in un browser reale con il pannello Network di DevTools, osserva le richieste mentre il contenuto si carica e cerca le chiamate XHR o fetch le cui risposte contengono i dati desiderati. Una volta individuate, spesso è possibile riprodurle interamente fuori dal browser, talvolta con un unico comando curl.
Octoparse integra questa possibilità direttamente nel proprio editor visuale. Il browser integrato espone lo stesso pannello di rete di DevTools, ma permette di selezionare una risposta API sottostante proprio come si selezionerebbe un elemento DOM: basta puntare e fare clic e l’attività usa quell’endpoint al posto del rendering della pagina. Il consueto ciclo “apri DevTools, trova la chiamata, copia le intestazioni, ricrea la richiesta” si riduce così a un solo passaggio visuale.
Ogni volta che è disponibile, questo è l’approccio migliore per le pagine renderizzate con JavaScript, e lo è più spesso di quanto si pensi. Vale la pena verificarlo prima di ricorrere a un browser.
Approccio 3: rilevare il rendering lato server
Alcuni siti che usano framework lato client implementano anche il rendering lato server (SSR) o la generazione statica del sito per migliorare prestazioni e SEO. In questi casi, la risposta HTML iniziale contiene già tutto il contenuto: può quindi bastare una richiesta HTTP leggera. Visualizza il sorgente della pagina (Cmd+U / Ctrl+U, non “Ispeziona”, che mostra il DOM attivo); se i dati si trovano già nell’HTML grezzo, puoi evitare del tutto il sovraccarico del browser. Alcuni siti si spingono oltre e servono contenuti diversi a User-Agent differenti, ad esempio eseguendo il pre-rendering per i crawler dei motori di ricerca. Impostare lo User-Agent della richiesta su quello di un bot di ricerca noto può talvolta rendere accessibile la versione renderizzata lato server di una pagina che altrimenti richiede JavaScript. Usa questa tecnica quando funziona, rispettando sempre i termini del sito.Alcuni consigli pratici quando serve un browser reale
Quando è necessario eseguire il rendering in un browser, le modalità di errore sono prevedibili:- Attendi l’elemento giusto, non l’evento “load”. L’evento load del browser si attiva quando HTML e risorse sono stati caricati, ma i contenuti renderizzati sul client potrebbero essere ancora in arrivo. Attendi la comparsa del selettore o del testo specifico che ti serve, non che la pagina sia genericamente “completata”.
- Fai attenzione al lazy loading. I contenuti renderizzati soltanto quando entrano nell’area visibile non esistono finché il web scraper non scorre la pagina. La maggior parte delle librerie di automazione del browser può simulare lo scorrimento; l’importante è sapere quando è necessario.
- Il routing lato client trae in inganno gli scraper tradizionali. Nelle SPA, il passaggio da
/productsa/products/42può modificare l’URL senza attivare una nuova richiesta HTTP. Una logica in attesa di eventipageloadnon rileva affatto la transizione; occorre attendere invece le modifiche del contenuto. - Lo scorrimento infinito e “carica altro” richiedono interazione, non soltanto osservazione. Per un approfondimento su questi modelli, consulta Gestire l’impaginazione.
Prova prima l’approccio meno costoso
Una strategia affidabile consiste nel verificare in quest’ordine:- Visualizza il sorgente. Se il contenuto è nell’HTML grezzo, il problema è risolto: basta una singola richiesta HTTP.
- Esamina le chiamate di rete. Se la pagina recupera i contenuti da un’API, chiama direttamente quell’API. È più veloce, leggera e affidabile.
- Renderizza in un browser reale. Quando nessuna delle opzioni precedenti è applicabile, esegui la pagina. Scegli il runtime più adatto al profilo dell’operatore e alle difese del sito di destinazione.