Formati e fonti di dati 4 min di lettura

Parsing delle sitemap: esplorare la mappa del sito prima della raccolta dati

Perché iniziare la raccolta dalla sitemap.xml: parsing delle sitemap indice, scelta degli URL giusti e risparmio sulla scansione del sito prima dello scraping.

TW
Team Web-Scraping.it
Raccolta dati per le esigenze del business
Pubblicato il 9 aprile 2025

La sitemap (mappa del sito) è un file XML con l’elenco degli URL di un sito che il proprietario mette a disposizione dei motori di ricerca e dei crawler. Per la raccolta dati la mappa del sito è preziosissima: invece di percorrere alla cieca i link di pagina in pagina, ricevi un elenco di indirizzi già pronto, spesso con la data dell’ultima modifica e la priorità. Per questo il parsing della sitemap è di solito il primo passo prima del parsing dell’HTML. Questo articolo prosegue la nostra panoramica sui formati di documenti; poiché la sitemap è un caso particolare di XML, le tecniche generali di lavoro con l’albero sono descritte nell’articolo sul parsing di XML.

Struttura del file

La sitemap standard è descritta dallo schema di sitemaps.org. Ogni URL è un elemento <url> con un <loc> obbligatorio e gli opzionali <lastmod>, <changefreq> e <priority>.

xml
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://example.com/product/101</loc>
    <lastmod>2026-05-12</lastmod>
    <priority>0.8</priority>
  </url>
  <url>
    <loc>https://example.com/product/102</loc>
    <lastmod>2026-06-01</lastmod>
  </url>
</urlset>

Un dettaglio importante: il namespace http://www.sitemaps.org/schemas/sitemap/0.9. Per colpa sua, la ricerca «ingenua» del tag loc senza tener conto del namespace restituirà il vuoto; è l’errore più frequente nel parsing delle mappe (per saperne di più sui namespace, vedi l’articolo sull’XML).

Sitemap index e sitemap annidate

Sui siti grandi un solo file non basta per tutti i link (il limite è di 50.000 URL o 50 MB), quindi si usa un indice di sitemap: un file con i link ad altre sitemap. L’elemento radice qui è <sitemapindex> e, all’interno, ci sono elementi <sitemap> con i rispettivi <loc>.

xml
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <sitemap><loc>https://example.com/sitemap-products.xml</loc></sitemap>
  <sitemap><loc>https://example.com/sitemap-articles.xml.gz</loc></sitemap>
</sitemapindex>

Per questo un parser affidabile deve essere ricorsivo: prima leggere l’indice e poi scaricare e analizzare una per una le sitemap annidate. Nota che i file annidati vengono spesso serviti compressi in gzip (.xml.gz) — vanno decompressi al volo.

Dove cercare la sitemap

L’indirizzo della sitemap di solito sta nel robots.txt, nella riga Sitemap:. Se lì non c’è, si controllano i percorsi standard /sitemap.xml e /sitemap_index.xml. Conviene partire proprio dal robots.txt: è il modo più affidabile per conoscere la posizione attuale.

Python

La via più trasparente: scaricare il file e analizzarlo come un normale XML con lxml, senza dimenticare il namespace e la ricorsione sull’indice.

python
import gzip
import requests
from lxml import etree

NS = {"sm": "http://www.sitemaps.org/schemas/sitemap/0.9"}

def fetch(url):
    data = requests.get(url, timeout=30).content
    if url.endswith(".gz"):
        data = gzip.decompress(data)
    return etree.fromstring(data)

def parse_sitemap(url, urls=None):
    urls = urls if urls is not None else []
    root = fetch(url)
    # se è un indice, scendiamo nelle sitemap annidate
    for loc in root.xpath("//sm:sitemap/sm:loc/text()", namespaces=NS):
        parse_sitemap(loc.strip(), urls)
    # link normali
    for loc in root.xpath("//sm:url/sm:loc/text()", namespaces=NS):
        urls.append(loc.strip())
    return urls

links = parse_sitemap("https://example.com/sitemap.xml")
print(len(links), "URL trovati")

Se non vuoi scrivere a mano ricorsione e gestione del gzip, c’è la libreria specializzata ultimate-sitemap-parser: trova la sitemap da sola, percorre gli indici e restituisce l’elenco piatto delle pagine.

python
from usp.tree import sitemap_tree_for_homepage

tree = sitemap_tree_for_homepage("https://example.com/")
for page in tree.all_pages():
    print(page.url, page.last_modified)

JavaScript / Node.js

In Node la sitemap si analizza comodamente con la coppia fetch e fast-xml-parser (lo stesso usato per l’XML).

javascript
const { XMLParser } = require("fast-xml-parser");

async function parseSitemap(url) {
  const xml = await (await fetch(url)).text();
  const parser = new XMLParser();
  const doc = parser.parse(xml);

  if (doc.sitemapindex) {
    const maps = [].concat(doc.sitemapindex.sitemap);
    const all = [];
    for (const m of maps) all.push(...await parseSitemap(m.loc));
    return all;
  }
  return [].concat(doc.urlset.url).map((u) => u.loc);
}

parseSitemap("https://example.com/sitemap.xml").then((urls) =>
  console.log(urls.length)
);

Che cosa fare con le date di aggiornamento

Il campo <lastmod> è il motivo principale per amare le mappe del sito. Confrontandolo con il momento della scansione precedente, puoi scaricare solo le pagine cambiate e non caricare il sito di richieste inutili. Questo trasforma uno scraping una tantum in un monitoraggio regolare efficiente: non percorri tutto il sito, solo il delta. Tieni presente che lastmod non è sempre compilato, né sempre in modo onesto: usalo come indizio, non come verità assoluta.

Una volta raccolto l’elenco degli URL comincia l’estrazione vera e propria dei dati dalle pagine — e quello è già compito del parsing dell’HTML. Se devi scansionare regolarmente un sito grande con sitemap indice, gzip e filtro per data, configureremo uno scraping chiavi in mano, pianificazione compresa, con la consegna del risultato nel formato che ti serve, per esempio CSV o Excel.