Salta al contenuto

Come raschiare dati Web nascosti

Raccogliere dati dal Web moderno può spesso sembrare un gioco a nascondino. Mentre dieci anni fa la maggior parte delle informazioni erano facilmente disponibili in HTML, oggigiorno gli sviluppatori amano nascondere e offuscare i dati, visualizzandoli dinamicamente con JavaScript.

Ciò rappresenta una sfida interessante per i raschiatori. Anche se non possiamo più fare affidamento sull’analisi del contenuto HTML grezzo, nella pagina sono ancora presenti numerosi dati: dobbiamo solo sapere dove cercare.

In questa guida completa, esploreremo vari metodi, strumenti e tecniche che possono essere utilizzati per estrarre dati web nascosti.

Cosa sono i dati web nascosti?

I dati web nascosti si riferiscono a tutti i dati che non sono direttamente visibili nel sorgente HTML grezzo della pagina. Ciò comprende:

  • Dati caricati dinamicamente tramite JavaScript dopo il caricamento della pagina. Ad esempio, rendendo il contenuto di a <div> tag inserendo elementi HTML creati dinamicamente.

  • Dati memorizzati in variabili JavaScript e oggetti incorporati in <script> tag. Spesso oggetti JSON contenenti interi set di dati.

  • Contenuto HTML generato sull'azione dell'utente tramite richieste AJAX. Ad esempio, l'espansione dei thread di commenti o l'impaginazione a scorrimento infinito.

  • Dati e metadati della richiesta API interna utilizzati dal frontend per funzionare. Ad esempio, token CSRF, informazioni utente, cache temporanee.

  • Dati offuscati e crittografati con l'obiettivo di impedire agli scraper di accedervi.

Il tema comune è che questi dati non sono disponibili nell'HTML originale restituito dal server, ma piuttosto generati successivamente dal JavaScript in esecuzione sulla pagina.

I moderni siti Web dinamici fanno molto affidamento su questa tecnica per creare esperienze frontend veloci. Tutti i dati possono essere nascosti e visualizzati con grazia in piccoli blocchi secondo necessità.

Sfortunatamente, questo significa che gli scraper devono lavorare un po’ di più per ottenere quei dati. Diamo un'occhiata ad alcuni modi in cui possiamo farlo in modo efficiente.

Trovare dati nascosti in HTML

Il primo passo è verificare se i dati che desideriamo sono effettivamente nascosti da qualche parte nel JavaScript della pagina.

Ecco un metodo semplice per verificare:

  • Carica la pagina di destinazione nel browser e individua un identificatore di dati univoco che vogliamo recuperare. Ad esempio, il nome o l'ID di un prodotto.

  • Disabilita JavaScript nel browser e ricarica la pagina. Questo può essere fatto negli strumenti per sviluppatori.

  • Controlla se l'identificatore univoco è ancora presente nel codice sorgente HTML non elaborato.

Se i dati scompaiono, molto probabilmente vengono visualizzati dinamicamente da JavaScript al caricamento della pagina.

Ora dobbiamo analizzare il sorgente HTML per scoprire dove e come genera quel contenuto.

Estrazione dei dati dai tag

Uno dei luoghi più comuni in cui risiedono i dati nascosti è l'interno <script> tag.

Possono trattarsi di oggetti JSON, variabili JavaScript, interi set di dati o codice che manipola la pagina.

Per esempio:

<html>
<body>

  <div id="product"></div>

  <script>
    // product data as javascript object 
    var data = {
      "product": {
        "name": "Super Product",
        "price": 99.99
      }
    }

    // data rendered on page load
    document.getElementById("product").innerHTML = data.product.name + ": £" + data.product.price;

  </script>

</body>  
</html>

Qui i dati effettivi del prodotto vengono memorizzati in una variabile oggetto JavaScript chiamata data.

Il prodotto <div> è vuoto all'inizio e popolato dinamicamente al caricamento della pagina.

Quindi, per estrarre questi dati, dobbiamo prima trovare quelli rilevanti <script> tag nell'HTML grezzo. Questo può essere fatto con qualsiasi libreria di analisi HTML come BeautifulSoup o Parsel:

# extract scripts from HTML with BeautifulSoup
from bs4 import BeautifulSoup

html = # page HTML 
soup = BeautifulSoup(html, ‘html.parser‘)

scripts = soup.find_all(‘script‘)

Successivamente dobbiamo estrarre i dati dal contenuto dello script in modo specifico.

Metodo 1: caricare come JSON

Se i dati sono un oggetto JSON valido, possiamo semplicemente caricarli direttamente con Python json modulo:

import json

# find script with data variable 
script = soup.find(‘script‘, text=lambda t: ‘data =‘ in t)

# load json directly
data = json.loads(script.string)

print(data[‘product‘])
# {‘name‘: ‘Super Product‘, ‘price‘: 99.99}

Funziona benissimo se il tag script lo specifica type="application/json".

Metodo 2: Corrispondenza Regex

Per dati più complessi, dovremo analizzare noi stessi il codice JavaScript grezzo. È qui che le espressioni regolari tornano utili.

Possiamo scansionare il codice ed estrarre parti che corrispondono a un modello, come il nostro oggetto dati.

import re
import json

script = soup.find(‘script‘, text=lambda t: ‘data =‘ in t)

# match the data object by surrounding syntax 
match = re.search(r‘data = ({.+})‘, script.string)

# load matched json 
data = json.loads(match.group(1))

print(data[‘product‘])  
# {‘name‘: ‘Super Product‘, ‘price‘: 99.99}

La chiave sta nel creare attentamente un modello regex che identifichi in modo univoco il set di dati che desideriamo dal resto del codice.

Metodo 3: analisi JavaScript

Per lo scraping avanzato, potremmo voler analizzare l'intero codice JavaScript, comprese variabili, funzioni e oggetti.

Ciò consente di estrarre qualsiasi dato mantenendo la struttura e il contesto originali.

Possiamo usare librerie come PyJavascript ed Js2Py per interpretare JavaScript in Python.

Ad esempio con PyJavascript:

import javascript

script = soup.find(‘script‘, text=lambda t: ‘data =‘ in t)

# init JavaScript interpreter 
js = javascript.Interpreter()

# run script to define data variable
js.execute(script.string)

# access parsed data object
print(js.context[‘data‘][‘product‘])
# {‘name‘: ‘Super Product‘, ‘price‘: 99.99} 

Ciò ci consente di attingere all'intero ambiente JavaScript, oltre ai soli set di dati che desideriamo.

Scraping dei dati API da JavaScript

Le API alimentano la maggior parte del comportamento dinamico sui siti Web moderni. JavaScript effettua richieste per caricare dati, inviare moduli o attivare interazioni.

Analizzando il codice della pagina, possiamo trovare questi endpoint API e imitare le richieste di estrazione dei dati.

Ad esempio, ecco un semplice script che carica i dati di prodotto da a /api/products/123 punto finale:

async function loadProduct(){

  let response = await fetch(‘/api/products/123‘);

  let product = await response.json();

  // render product data to page
  document.getElementById("product").innerHTML = product.name;

}

loadProduct();

Una volta individuato questo script nell'HTML, possiamo:

  • Estrai l'URL dell'API dal file fetch() chiamata

  • Analizzare i formati di richiesta e risposta AJAX

  • Replica la richiesta API direttamente in Python con librerie come Requests

Ciò consente di estrarre dati dalle API su cui si basa JavaScript senza eseguire alcun codice del browser.

Trovare dati nelle variabili JavaScript

I dati della pagina vengono comunemente archiviati anche direttamente nelle variabili JavaScript.

Per esempio:

// javascript data
var products = [
  {name: "Product 1", price: 19.99}, 
  {name: "Product 2", price: 24.99}
];

function renderProducts(){
  // loop through products and render HTML
} 

Qui l'elenco completo dei prodotti è memorizzato in una variabile chiamata products.

Per estrarlo, dobbiamo prima trovare il nome della variabile che corrisponde alla nostra struttura dati di destinazione. Possiamo usare un approccio regex simile:

import re
import json

# find products variable
script = soup.find(‘script‘, text=lambda t: ‘var products =‘ in t)

# match products json
match = re.search(r‘var products = ({.+});‘, script.string)  
data = json.loads(match.group(1))

print(data)
# [{name: "Product 1", price: 19.99}, {name: "Product 2", price: 24.99}]

Se la struttura dei dati è più complessa, possiamo analizzare l'intero ambiente JavaScript per accedere a qualsiasi variabile nell'ambito.

Scraping di contenuti caricati tramite AJAX

I siti Web caricano spesso i contenuti in modo dinamico tramite AJAX dopo il caricamento della pagina.

Ad esempio, espansione dei thread di commenti, paginazione a scorrimento infinito o schede.

Questo contenuto non è presente nell'HTML iniziale ma richiesto dal server secondo necessità.

Possiamo raschiare questi frammenti AJAX:

  • Monitoraggio delle richieste di rete sulla pagina per identificare gli URL AJAX.

  • Ricostruire richieste AJAX e inviarle direttamente dal codice Python.

  • Analisi delle risposte AJAX che contengono dati HTML/JSON.

Ad esempio, considera questo script che carica i dati impaginati durante lo scorrimento:

// initially loaded page data
var results = [ /* initial page of data */]; 

// paginate on scroll
window.addEventListener(‘scroll‘, function() {

  var page = results.length / 20 + 1;

  // request next page
  fetch(‘/data?page=‘ + page)
    .then(res => res.json())
    .then(data => {
      results.push(...data);

      // render new data
    });

});

Qui possiamo vedere che sta richiedendo pagine da /data endpoint e aggiungendo contenuto a results variabile.

Possiamo replicare queste richieste e raccogliere direttamente i dati, evitando di dover analizzare l'intero codice HTML renderizzato.

Esecuzione di JavaScript con browser headless

Per il massimo in termini di scraping di contenuti dinamici, possiamo avviare un browser headless completo, caricare la pagina e accedere direttamente all'ambiente JavaScript.

Ciò consente di valutare il codice, caricare contenuti dinamici e accedere a tutti i dati, funzioni o elementi DOM disponibili nella pagina live.

Ecco un esempio con Playwright in Python:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:

  browser = p.chromium.launch()
  page = browser.new_page()

  page.goto(‘https://targetpage.com‘)

  # evaluate browser context to get data
  data = page.evaluate(‘window.products‘) 

  browser.close()

print(data)

La chiave è usare page.evaluate() per eseguire codice JavaScript personalizzato nel contesto della pagina caricata.

Questo ci dà accesso completo per recuperare qualsiasi dato altrimenti nascosto.

Lo svantaggio è dover avviare un’istanza completa del browser, che è più lenta delle richieste HTTP dirette. Quindi questo metodo dovrebbe essere usato con parsimonia per le pagine complesse.

Dati offuscati e crittografati

I siti web spesso offuscano deliberatamente il loro JavaScript per impedire lo scraping.

Ecco alcuni esempi:

  • Minimizzare i nomi di variabili e funzioni in caratteri senza significato come a, b, fn1()

  • Suddivisione dei set di dati su più variabili e script

  • Crittografia/codifica dei dati in modo che non siano leggibili dall'uomo

  • Assemblaggio dinamico dei dati in fase di esecuzione da pezzi frammentati

  • Tecniche di protezione del codice come compressione, offuscamento, anti-debug, esecuzione di VM

Ciò può rendere l'analisi di JavaScript molto complicata. Piccole modifiche al codice possono facilmente rompere i nostri raschiatori.

Esistono alcuni modi per gestire le pagine fortemente offuscate:

  • Utilizza browser headless come Playwright o Puppeteer per caricare il codice eseguito anziché analizzare direttamente la fonte offuscata.

  • Traccia l'esecuzione del codice per comprendere come vengono assemblati i dati, ad esempio utilizzando gli strumenti di sviluppo del browser o l'inoltro del traffico del browser.

  • Analizza come gli utenti reali interagiscono con la pagina per identificare le origini dati.

  • I modelli corrispondono a strutture di dati note, come nomi di prodotti, prezzi, ID, per individuare parti di codice rilevanti anche se le variabili sono offuscate.

  • Per la crittografia, prova a individuare le chiavi di crittografia o esegui il reverse engineering degli algoritmi di decrittografia.

Nel tempo possiamo sviluppare la resilienza evolvendo gli scraper per adattarci ai cambiamenti di offuscamento.

Rimozione di API nascoste con proxy

Le API web nascoste spesso utilizzano tecniche anti-scraping avanzate come la limitazione della velocità IP, il captcha e il rilevamento dei bot per impedire l'accesso.

È qui che i proxy tornano molto utili per lo scraping. Instradando le richieste tramite IP residenziali, possiamo aggirare molte protezioni e accedere alle API su vasta scala.

Alcuni suggerimenti per lo scraping con i proxy:

  • Utilizza la rotazione regolare del proxy per evitare di essere bloccato su IP specifici

  • Abilita la rotazione dei proxy in base alle regioni o agli ISP per un'ampia diversità

  • Utilizza proxy backconnect che forniscono migliaia di IP univoci da scorrere

  • Limita i tassi di richiesta per proxy per imitare il comportamento reale degli utenti

  • Utilizza l'autorizzazione proxy per impersonare dispositivi reali, non solo IP anonimi

  • Monitora e gestisci blocchi comuni come captcha, pagine di blocco, 429

Con la giusta configurazione del proxy, possiamo accedere praticamente a qualsiasi sito di destinazione o API nascosta.

Servizi di scraping per dati nascosti

Esistono anche servizi di scraping gestiti creati appositamente per estrarre i dati renderizzati in JavaScript.

Questi forniscono automazione del browser, gestione proxy e funzionalità di esecuzione JavaScript.

Ecco alcuni esempi:

RaschiareApe – API browser e proxy in grado di valutare JS nelle pagine.

API raschietto – API del browser headless con rotazione automatica del proxy.

Apifica – Runtime dell'attore per l'automazione del browser su larga scala.

ScrapeOps – Generatore di automazione del browser visivo con estrazione JS.

ScrapFly – API di scraping non bloccabile con milioni di proxy residenziali backconnect.

Questi servizi gestiscono tutte le complessità del rendering dinamico delle pagine e semplificano il recupero dei dati nascosti.

Punti chiave

Ecco i punti chiave per lo scraping dei dati dei siti Web nascosti:

  • Ispeziona le pagine senza JavaScript per verificare che i dati vengano caricati dinamicamente

  • Estrai e analizza script, variabili e oggetti JSON da HTML

  • Analizza e replica le richieste AJAX per accedere alle API nascoste

  • Utilizza proxy e browser headless quando necessario per siti JS pesanti

  • Corrispondenza di pattern e reverse engineering del codice offuscato

  • Adattare i raschiatori per gestire le protezioni anti-bot

Con le tecniche giuste, è possibile estrarre praticamente tutti i dati dei siti Web pubblici. Dobbiamo solo sapere dove guardare!

Tag:

Partecipa alla conversazione

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati con *