CMS e piattaforme 11 min di lettura

Scraper per WordPress

Come fare scraping per i siti WordPress e riempirli con i contenuti raccolti: REST API, XML-RPC, plugin di importazione e soluzioni su misura.

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

Il web scraping è uno degli strumenti più richiesti per i siti realizzati con WordPress. Ti permette di riempire il sito in automatico con contenuti sempre aggiornati: tassi di cambio, notizie, previsioni meteo, prodotti dei fornitori e molto altro. In questo articolo vedremo quali plugin pronti esistono, in quali casi conviene scrivere uno scraper in PHP su misura e analizzeremo quattro scenari pratici per integrare lo scraping in WordPress.

Se vuoi approfondire la tecnologia stessa di estrazione e analisi dei dati, ti consigliamo l’articolo dedicato «Web scraping in PHP», dove sono descritti nel dettaglio i principi di funzionamento, le librerie (cURL, Guzzle, Simple HTML DOM, Symfony DomCrawler) e le insidie tipiche. Qui mettiamo l’accento proprio sull’integrazione con WordPress.


Cos’è lo scraping nel contesto di WordPress

Lo scraping (web scraping) è la raccolta automatica di dati da fonti esterne: siti web, API, feed RSS, listini prezzi. In WordPress, di solito, questi dati non basta ottenerli; bisogna anche:

  • salvarli nel database (come articoli, prodotti, campi meta o opzioni);
  • metterli in cache, per non gravare né sulla fonte esterna né sul proprio server;
  • aggiornarli in modo pianificato (tramite wp_cron o il cron di sistema);
  • mostrarli nel frontend (tramite shortcode, widget o blocchi Gutenberg).

Proprio per questo uno «scraper per WordPress» non è un semplice script che scarica qualcosa, ma un modulo completo, integrato nell’ecosistema del CMS.


Panoramica dei plugin esistenti

Prima di scrivere una soluzione propria, ha senso valutare i plugin già pronti. Coprono molte attività tipiche senza una sola riga di codice.

WP All Import

Uno degli strumenti di importazione più potenti. Accetta XML, CSV e i formati dei listini prezzi, permette di mappare in modo visuale i campi della fonte su quelli di articoli, prodotti WooCommerce o utenti. Supporta l’importazione pianificata e l’aggiornamento dei record già importati. Si presta bene allo scenario dei prodotti di un fornitore, ma richiede che la fonte fornisca un feed strutturato.

Pro: mappatura flessibile, interfaccia amichevole, aggiornamento affidabile. Contro: le funzioni avanzate stanno nella versione a pagamento; non fa scraping di pagine HTML arbitrarie senza un feed già preparato.

Content Egg

Plugin aggregatore per l’affiliate e il content marketing: sa recuperare prodotti, prezzi, recensioni e altri contenuti da una moltitudine di fonti e API. Si usa spesso per confrontare i prezzi e completare le schede prodotto.

Pro: molti moduli-sorgente pronti, template di output. Contro: è tarato su scenari specifici (affiliazioni, marketplace) e ha una propria logica di visualizzazione.

WP RSS Aggregator / Feedzy

Plugin specializzati nell’importazione di feed RSS e Atom. Permettono di combinare più feed, filtrare per parole chiave e trasformare gli elementi del feed in articoli WordPress.

Pro: configurazione semplice per notizie e RSS, filtri e deduplicazione. Contro: sono limitati al formato feed; per l’HTML arbitrario non vanno bene.

Scraper universali (WP Content Pilot, plugin di scraping)

Esistono plugin capaci di estrarre dati da pagine arbitrarie tramite selettori CSS. Sono la cosa più vicina a uno scraper «vero», ma qualsiasi cambio nel layout della fonte rompe la configurazione, e implementarci una logica di post-elaborazione complessa è difficile.

Quando i plugin non bastano

Le soluzioni pronte funzionano alla grande finché il compito è standard. Ma appena compare una fonte atipica, una logica di trasformazione complessa, un’autenticazione lato fornitore o requisiti specifici di caching, la flessibilità del plugin smette di bastare. In quel caso si scrive uno scraper su misura.


Uno scraper personalizzato in PHP dentro WordPress

Il vantaggio principale di una soluzione propria è il controllo totale. Decidi tu come ottenere i dati, come pulirli, dove salvarli e quando aggiornarli. WordPress mette a disposizione strumenti comodi per farlo, e non serve affatto ricorrere al «nudo» file_get_contents.

I «mattoni» di base su cui si costruisce qualsiasi scraper per WordPress:

php
// 1. Recupero dei dati: tramite la HTTP API integrata di WordPress
$response = wp_remote_get( 'https://example.com/data', array(
    'timeout' => 15,
    'headers' => array( 'User-Agent' => 'MySiteBot/1.0' ),
) );

if ( is_wp_error( $response ) ) {
    error_log( 'Errore nella richiesta: ' . $response->get_error_message() );
    return;
}

$body = wp_remote_retrieve_body( $response );
php
// 2. Caching tramite la Transients API, per non interrogare la fonte a ogni visualizzazione
function my_get_cached_data() {
    $cache_key = 'my_parser_data';
    $data = get_transient( $cache_key );

    if ( false === $data ) {
        $data = my_fetch_and_parse(); // la tua funzione di scraping
        set_transient( $cache_key, $data, HOUR_IN_SECONDS );
    }

    return $data;
}
php
// 3. Aggiornamento pianificato tramite WP-Cron
add_action( 'init', function () {
    if ( ! wp_next_scheduled( 'my_parser_update' ) ) {
        wp_schedule_event( time(), 'hourly', 'my_parser_update' );
    }
} );

add_action( 'my_parser_update', 'my_fetch_and_parse' );

L’analisi dettagliata delle librerie di parsing HTML, della gestione delle codifiche, dell’aggiramento delle protezioni e della costruzione di uno scraper robusto è nell’articolo dedicato «Web scraping in PHP». Qui sotto ci basiamo su quei principi e mostriamo proprio le specificità di WordPress.

Passiamo ora agli scenari concreti.


Scenario 1. Scraping dei tassi di cambio

Un compito tipico di un negozio online o di un sito di contenuti: mostrare i prezzi in più valute contemporaneamente e convertirli in automatico. Come fonte servono i dati ufficiali di una banca centrale — ad esempio il feed XML della Banca Centrale Europea con i tassi di riferimento dell’euro.

La logica è semplice: una volta al giorno scarichiamo l’XML con i tassi, lo analizziamo, salviamo il risultato nelle opzioni di WordPress e lo usiamo quando mostriamo i prezzi.

php
function parse_currency_rates() {
    $url = 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'; // feed dei tassi di riferimento della BCE
    $response = wp_remote_get( $url, array( 'timeout' => 15 ) );

    if ( is_wp_error( $response ) ) {
        return;
    }

    $xml = simplexml_load_string( wp_remote_retrieve_body( $response ) );
    if ( false === $xml ) {
        return;
    }

    $xml->registerXPathNamespace( 'e', 'http://www.ecb.int/vocabulary/2002-08-01/eurofxref' );

    $rates = array();
    foreach ( $xml->xpath( '//e:Cube[@currency]' ) as $cube ) {
        $code  = (string) $cube['currency'];          // USD, GBP ...
        $value = (float) $cube['rate'];
        $rates[ $code ] = $value;                     // unità di valuta per 1 EUR
    }

    update_option( 'my_currency_rates', $rates );
    update_option( 'my_currency_rates_updated', current_time( 'mysql' ) );
}
add_action( 'my_currency_update', 'parse_currency_rates' );

Conversione di un prezzo nella valuta desiderata:

php
function convert_price( $eur_amount, $currency = 'USD' ) {
    $rates = get_option( 'my_currency_rates', array() );
    if ( empty( $rates[ $currency ] ) ) {
        return $eur_amount;
    }
    return round( $eur_amount * $rates[ $currency ], 2 );
}

E uno shortcode per mostrare il tasso di cambio in una pagina:

php
add_shortcode( 'currency_rate', function ( $atts ) {
    $atts  = shortcode_atts( array( 'code' => 'USD' ), $atts );
    $rates = get_option( 'my_currency_rates', array() );
    $code  = strtoupper( $atts['code'] );

    return isset( $rates[ $code ] )
        ? esc_html( '1 € = ' . number_format( $rates[ $code ], 2 ) . ' ' . $code )
        : '—';
} );
// Uso: [currency_rate code="GBP"]

L’analisi completa dei formati XML/JSON delle banche centrali, della gestione di più valute e del calcolo dei cross rate è nell’articolo dedicato «Scraping dei tassi di cambio».


Scenario 2. Scraping di notizie e RSS

Il secondo scenario popolare è riempire il sito di notizie in automatico. Qui WordPress offre un bel bonus: il core include già un parser di feed integrato, fetch_feed(), basato sulla libreria SimplePie. È il modo più affidabile di lavorare con gli RSS senza reinventare la ruota.

php
function import_news_from_rss( $feed_url ) {
    include_once ABSPATH . WPINC . '/feed.php';

    $feed = fetch_feed( $feed_url );
    if ( is_wp_error( $feed ) ) {
        return;
    }

    $max_items = $feed->get_item_quantity( 10 );
    $items     = $feed->get_items( 0, $max_items );

    foreach ( $items as $item ) {
        $guid = $item->get_id();

        // Protezione dai duplicati: cerchiamo un articolo con lo stesso GUID di origine
        $existing = get_posts( array(
            'meta_key'   => '_source_guid',
            'meta_value' => $guid,
            'post_type'  => 'post',
            'fields'     => 'ids',
        ) );
        if ( $existing ) {
            continue;
        }

        $post_id = wp_insert_post( array(
            'post_title'   => sanitize_text_field( $item->get_title() ),
            'post_content' => wp_kses_post( $item->get_content() ),
            'post_date'    => $item->get_date( 'Y-m-d H:i:s' ),
            'post_status'  => 'draft', // in moderazione, per evitare contenuti spazzatura
            'post_type'    => 'post',
        ) );

        if ( $post_id && ! is_wp_error( $post_id ) ) {
            update_post_meta( $post_id, '_source_guid', $guid );
        }
    }
}

Avviamo l’importazione in modo pianificato:

php
add_action( 'my_news_import', function () {
    import_news_from_rss( 'https://example.com/feed/' );
} );

Se invece la fonte non offre RSS e le notizie vanno estratte direttamente dalla pagina HTML tramite selettori, siamo già nel campo dello scraping vero e proprio, con l’analisi del layout. Progetti di questo tipo li realizziamo come estrazione di notizie chiavi in mano: configuriamo l’estrazione di titoli, date, immagini e testi da siti arbitrari tenendo conto della loro struttura.

Le finezze del lavoro con i feed, i formati RSS 2.0 e Atom, il filtraggio e la combinazione di più fonti li trattiamo nell’articolo dedicato agli RSS.


Scenario 3. Scraping delle previsioni meteo

Il widget meteo è una richiesta frequente per portali locali, siti di hotel e agenzie di viaggio. I dati di solito si prendono da un’API meteo che restituisce JSON. Il compito, nel contesto di WordPress, è integrare con cura questo widget nel sito: ottenere le previsioni, metterle in cache per un breve periodo e mostrarle tramite uno shortcode o un blocco.

php
function get_weather( $city = 'Roma' ) {
    $cache_key = 'weather_' . sanitize_key( $city );
    $weather   = get_transient( $cache_key );

    if ( false !== $weather ) {
        return $weather; // le serviamo dalla cache
    }

    $url = add_query_arg( array(
        'q'     => $city,
        'units' => 'metric',
        'lang'  => 'it',
        'appid' => 'YOUR_API_KEY',
    ), 'https://api.example-weather.com/data/forecast' );

    $response = wp_remote_get( $url, array( 'timeout' => 10 ) );
    if ( is_wp_error( $response ) ) {
        return null;
    }

    $data = json_decode( wp_remote_retrieve_body( $response ), true );

    $weather = array(
        'temp'        => $data['main']['temp'] ?? null,
        'description' => $data['weather'][0]['description'] ?? '',
        'icon'        => $data['weather'][0]['icon'] ?? '',
    );

    // Il meteo cambia spesso: mettiamo in cache solo per 30 minuti
    set_transient( $cache_key, $weather, 30 * MINUTE_IN_SECONDS );

    return $weather;
}

Shortcode per inserire il widget in qualsiasi articolo o pagina:

php
add_shortcode( 'weather', function ( $atts ) {
    $atts    = shortcode_atts( array( 'city' => 'Roma' ), $atts );
    $weather = get_weather( $atts['city'] );

    if ( empty( $weather ) ) {
        return '<span class="weather-error">Meteo non disponibile</span>';
    }

    return sprintf(
        '<div class="weather-widget">
            <span class="weather-city">%s</span>
            <span class="weather-temp">%s°C</span>
            <span class="weather-desc">%s</span>
        </div>',
        esc_html( $atts['city'] ),
        esc_html( round( $weather['temp'] ) ),
        esc_html( $weather['description'] )
    );
} );
// Uso: [weather city="Milano"]

I punti chiave specifici di WordPress: un TTL di cache breve (le previsioni invecchiano in fretta), l’output tramite shortcode/widget e l’escape obbligatorio dei dati prima della visualizzazione.

La guida completa alle fonti di dati meteo, al parsing delle previsioni su più giorni e alla gestione della geolocalizzazione è nell’articolo sullo scraping di dati meteo; qui l’abbiamo visto proprio nell’ottica dell’integrazione in un sito WordPress.


Scenario 4. Scraping del sito di un fornitore e importazione dei prodotti in WooCommerce

Lo scenario più completo: riempire in automatico un negozio online con i prodotti di un fornitore. La fonte può essere un listino prezzi (CSV/XML) o il sito stesso del fornitore, da analizzare a partire dall’HTML. Il risultato viene importato in WooCommerce sotto forma di prodotti con prezzi, disponibilità, immagini e categorie.

Vediamo l’importazione da un feed strutturato (la variante più stabile):

php
function import_supplier_products() {
    // Protezione dalle esecuzioni in parallelo
    if ( get_transient( 'import_lock' ) ) {
        return;
    }
    set_transient( 'import_lock', 1, 10 * MINUTE_IN_SECONDS );

    $response = wp_remote_get( 'https://supplier.example.com/price.xml', array(
        'timeout' => 60,
    ) );

    if ( is_wp_error( $response ) ) {
        delete_transient( 'import_lock' );
        return;
    }

    $xml = simplexml_load_string( wp_remote_retrieve_body( $response ) );

    foreach ( $xml->offer as $offer ) {
        $sku   = (string) $offer->sku;
        $name  = (string) $offer->name;
        $price = (float) $offer->price;
        $stock = (int) $offer->stock;

        upsert_product( $sku, $name, $price, $stock, (string) $offer->picture );
    }

    delete_transient( 'import_lock' );
}

La funzione «crea o aggiorna» prodotto (upsert): cerca il prodotto per codice articolo (SKU) e aggiorna quello esistente oppure ne crea uno nuovo:

php
function upsert_product( $sku, $name, $price, $stock, $image_url = '' ) {
    $product_id = wc_get_product_id_by_sku( $sku );

    if ( $product_id ) {
        // Il prodotto esiste già: aggiorniamo solo prezzo e stock
        $product = wc_get_product( $product_id );
    } else {
        // Prodotto nuovo
        $product = new WC_Product_Simple();
        $product->set_sku( $sku );
        $product->set_name( $name );

        // L'immagine si scarica solo alla creazione del prodotto
        if ( $image_url ) {
            $attach_id = media_sideload_image( $image_url, 0, $name, 'id' );
            if ( ! is_wp_error( $attach_id ) ) {
                $product->set_image_id( $attach_id );
            }
        }
    }

    $product->set_regular_price( (string) $price );
    $product->set_stock_quantity( $stock );
    $product->set_manage_stock( true );
    $product->set_stock_status( $stock > 0 ? 'instock' : 'outofstock' );

    $product->save();
}

Avvio dell’importazione in modo pianificato (ad esempio due volte al giorno):

php
add_action( 'init', function () {
    if ( ! wp_next_scheduled( 'supplier_import_event' ) ) {
        wp_schedule_event( time(), 'twicedaily', 'supplier_import_event' );
    }
} );
add_action( 'supplier_import_event', 'import_supplier_products' );

A cosa fare attenzione in questo scenario:

  • Identificazione tramite SKU. Il codice articolo è la chiave più affidabile per abbinare i prodotti tra fornitore e negozio.
  • Le immagini si scaricano una sola volta. media_sideload_image() è un’operazione costosa; non serve ripeterla a ogni aggiornamento.
  • Elaborazione a lotti. I listini grandi (decine di migliaia di referenze) conviene elaborarli a blocchi (batch), per non scontrarsi con i limiti di tempo e memoria di PHP.
  • Ritiro dalla vendita. I prodotti spariti dal listino del fornitore conviene passarli allo stato «esaurito» invece di eliminarli.

Se il fornitore non fornisce un feed e le schede prodotto vanno estratte direttamente dalle pagine HTML del suo sito, il lavoro diventa più impegnativo e ha le sue particolarità (paginazione, caricamento dinamico, protezione anti-bot). I principi di questo tipo di analisi sono descritti nel dettaglio nell’articolo «Web scraping in PHP».


Raccomandazioni tecniche

Alcune regole universali che renderanno più affidabile qualsiasi scraper per WordPress:

  1. Usa la HTTP API di WordPress (wp_remote_get/wp_remote_post) al posto di file_get_contents e del cURL «grezzo»: tiene conto delle impostazioni proxy, dei timeout e dei filtri del CMS.
  2. Metti in cache con la Transients API. Riduce il carico sia sul tuo server sia sulla fonte.
  3. Non fare scraping al volo al caricamento della pagina. Lo scraping pesante deve girare in background via cron; il frontend legge dati già pronti.
  4. Sostituisci WP-Cron con il cron di sistema per i compiti pesanti: WP-Cron scatta solo quando qualcuno visita il sito e non è adatto a importazioni lunghe.
  5. Fai sempre l’escape dei dati prima di mostrarli (esc_html, esc_url, wp_kses_post): una fonte esterna non va mai considerata affidabile.
  6. Registra gli errori e controlla is_wp_error() a ogni passo: la fonte esterna può non essere raggiungibile, cambiare formato o restituire spazzatura.
  7. Attieniti alle norme legali ed etiche: rispetta robots.txt, i limiti di richieste e le condizioni d’uso della fonte.

Conclusione

Lo scraping è un modo potente di automatizzare il riempimento di un sito WordPress. Per i compiti tipici spesso bastano plugin pronti come WP All Import o Feedzy. Ma appena la fonte o la logica di elaborazione escono dallo standard, uno scraper in PHP su misura offre un controllo e una flessibilità incomparabilmente maggiori.

Abbiamo esaminato quattro scenari pratici — tassi di cambio, notizie e RSS, previsioni meteo e importazione dei prodotti di un fornitore in WooCommerce — e abbiamo mostrato come integrare ciascuno di essi nell’ecosistema di WordPress con la HTTP API, i transient e il cron.

Vuoi approfondire la tecnologia stessa dell’analisi dei dati? Parti dall’articolo di base «Web scraping in PHP». E se ti serve uno scraper pronto per il tuo caso, ce ne occupiamo noi: dalla configurazione dell’estrazione di notizie all’importazione completa del catalogo di un fornitore.