Molti SEO specialist hanno un passato (o un presente) da programmatori. Questo guest post, scritto da Matteo Boffo (un appassionato e studioso di contenuti autogenerati e spam engine), è dedicato proprio a chi mangia quotidianamente “pane e codice”: si tratta di una una piccola “guida”/tool scritto in PHP, facilmente adattabile per seguire una o più query su Google, e avere l’andamento nel tempo della posizione di un dominio per quella query; il tool riesce a trovare il dominio cercato dalla posizione 1 alla posizione 9999. Obiettivo di questa guida è fornire un metodo semplice per seguire il posizionamento di un certo dominio per un certo numero di query di ricerca in Google. Premetto che questo script non necessita di una API_Key da richiedere sul sito di Google quindi lo possono provare tutti senza registrazioni varie ecc… Lo dovete vedere con un’ottica di tutorial, lo script è migliorabile in tanti punti ma come guida e punto di partenza può bastare. I requisiti necessari sono:

  • un server web (Apache) con interprete PHP (con modulo CURL attivato)
  • MySQL (una versione anche non molto recente in quanto non si fa uso di particolari caratteristiche)
  • la libreria simplehtmldom scaricabile dal sito http://simplehtmldom.sourceforge.net/

Personalmente uso, su una macchina con SO Windows XP, il pacchetto XAMPP che, in maniera semplice e veloce mi mette a disposizione i requisiti necessari sopra descritti (la libreria va scaricata). Nel seguente schema potete vedere l’architettura dell’applicazione:

Architettura dell’applicazione

Vediamo innanzitutto le tabelle contenute nel database (colore giallo nello schema) Nel database ci sono due tabelle:

  1. query_mdr che contiene un unico campo (query) che contiene tutte le query che vogliamo analizzare
  2. serp che contiene lo storico delle serp prelevate

Il dump della struttura della tabella query_mdr che serve a noi è il seguente: SET SQL_MODE=”NO_AUTO_VALUE_ON_ZERO”; 

CREATE TABLE `query_mdr` (

  `query` varchar(255) character set utf8 NOT NULL,

  PRIMARY KEY  (`query`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci; Nel campo query andremo ad inserire le query. Ad esempio un possibile contenuto della tabella potrebbe essere:

abbigliamento casual
Abbigliamento estivo
Jeans corti
…..

Il dump della struttura della tabella serp che serve a noi è il seguente:

SET SQL_MODE=”NO_AUTO_VALUE_ON_ZERO”;

CREATE TABLE `serp` (

  `query` varchar(255) character set utf8 NOT NULL,

  `rilevazione` varchar(12) character set utf8 NOT NULL,

  `posizione` int(11) NOT NULL,

  `urlserp` varchar(255) character set utf8 NOT NULL,

  PRIMARY KEY  (`query`,`rilevazione`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

Come potete vedere la tabella è la seguente:

query rilevazione posizione urlserp
abiti+eleganti+premaman 200806060052 9 www…..

Analizziamo i quattro campi:

  • query: contiene la query da chiedere a Google. Gli spazi sono cambiati nel carattere ‘+’
  • rilevazione: è formata da una stringa anno-mese-giorno-ora-minuti. Ho scelto di non utilizzare un campo di tipo data, ma una stringa in formato iso per semplicità e perché riesco a gestirmi meglio l’informazione contenuta nel campo (si può essere d’accordo o meno su questa scelta ma ricordo che questo script è un prototipo)
  • posizione: la posizione nella serp ritornata da Google. Questo script segue dalla posizione 1 alla 9999
  • urlserp: questo campo contiene l’url presentato da Google e ad oggi scritto in verde sotto alla descrizione del risultato (vedi immagine)

URL presentato da Google

Vediamo ora lo script in PHP che gestisce il tutto (colore verde nello schema) Prima di vedere il codice sorgente e commentarlo vi dico subito che lo script gira per circa un’ora in maniera continuativa. Il carico sul server non è elevato in quanto ha dei tempi “morti” casuali per non fare troppe richieste al server di Google, in quanto quest’ultimo altrimenti blocca l’accesso allo scaricamento della pagina. Lo script va lanciato un paio di volte al giorno (va beh, decidete voi quando), ovviamente questo dipende da quante query volete analizzare. Vediamo ora il codice sorgente (i commenti sono ingiallo, le parti da modificare perpersonalizzare lo script in rosso):  <?php

  //definisco una funzione per recuperare una pagina tramite il modulo CURL

  function get_url_contents($url){

    $crl = curl_init();

    $timeout = 10;

    curl_setopt ($crl, CURLOPT_URL,$url);

    curl_setopt ($crl, CURLOPT_RETURNTRANSFER, 1);

    curl_setopt ($crl, CURLOPT_CONNECTTIMEOUT, $timeout);

    curl_setopt ($crl, CURLOPT_USERAGENT, “Firefox (WindowsXP) – Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6”);

    $ret = curl_exec($crl);

    curl_close($crl);

    return $ret;

  } 

  //Mi serve per far durare lo script non più di 1 ora

  $inizio_time = time();

  include(‘./simple_html_dom.php’);//richiamo la libreria simplehtmldom

  $conn_database = mysql_connect(‘localhost’,’xxxxx‘,’aaaaa‘) or die(‘Impossibile connettersi al server MySQL.’);//primo parametro->nome utente; secondo parametro->password per collegarsi al db

  //selezionio il database

  mysql_select_db(“ddddddd“,$conn_database) or die(“Impossibile selezionare il database.”);//parametro->seleziono il database 

  //url che devo cercare nelle serp, in questo caso è un dominio di mia appartenenza

  $stringa_url = “www.xxxxxxxxxxxxxxxxxxx.com“; 

  //Ciclo tra tutte le query presenti nella tabella query_mdr

  $sql_select_query_mdr = “SELECT * from query_mdr”;

  $result_select_query_mdr = mysql_query($sql_select_query_mdr, $conn_database);

  while ($riga1=mysql_fetch_array($result_select_query_mdr, MYSQL_ASSOC)) {

    //trasformo la query prelevata mettendo + al posto degli spazi

    $query_mdr_trasformata = preg_replace( ‘/&{1,1}/’,’%26′, preg_replace  ( ‘/ {1,1}/’  , ‘+’  , $riga1[‘query’]  ) );

    /************ INIZIO ANALISI QUERY  **********/

    $query = $query_mdr_trasformata;

    $pagina_serp = 1;// prima pagina

    $trovato_risultato = 0; //non trovato nella serp

    $data_rilevazione = date(‘YmdHi’);

    /*Controllo l’ultima volta che è stata lanciata la query. Devono essere passate almeno 12 ore dall’analisi precedente*/

    $sql_verifica_orario = “SELECT rilevazione from serp where query='”.$query.”‘ order by rilevazione DESC limit 0,1″;

    $result_verifica_orario = mysql_query($sql_verifica_orario, $conn_database);

    $data_ultima_registrata = 0;

    $differenza = 0;

    $rec = 0;

    while ($riga_cat=mysql_fetch_array($result_verifica_orario, MYSQL_ASSOC)) {

      $data_ultima_registrata = $riga_cat[‘rilevazione’];

      $differenza = $data_rilevazione – $data_ultima_registrata;

      $rec++;

    }

    $processare_query = FALSE;

    if ( ($differenza > 1200 ) OR ( $differenza==0 AND $rec==0 ) ){ //12ore

      $processare_query = TRUE;

      echo ‘Posso processare la query<br>’;

    }

    else {

      echo ‘Sono passate MENO di 12 ore. Non processo la query: ‘.$query.'<br>’;

    }

    //A questo punto prelevo da Google i risultati e inizio a scandagliare la SERP.

    for ( $pagina_serp = 1;($pagina_serp < 101) AND ($trovato_risultato == 0) AND $processare_query; $pagina_serp++ ){ // 100 pagine=max 1000 risultati

      //decido l’url della pagina da scaricare a seconda che sia la prima pagina o dalla seconda in poi

      if ( $pagina_serp == 1 ){

        $url = “http://www.google.it/search?hl=it&q=”.$query.”&btnG=Cerca+con+Google&meta=”;

      }

      else {

        $str_pagina_url = ($pagina_serp-1)*10;

        $url = “http://www.google.it/search?hl=it&q=”.$query.”&start=”.$str_pagina_url.”&sa=N”;

      }

      $contenuto_pagina = ”;

      $contenuto_pagina = get_url_contents($url); //scarico la pagina

      $handle = fopen(‘./google.txt’,’w’);//mi salvo la pagina in un file

      fwrite($handle, $contenuto_pagina);

      fclose($handle);

      $dom = NULL;

      unset($dom);

      $dom = file_get_dom(‘./google.txt’);

      // Prelevato il contenuto della pagina. Prelevo i link dalla pagina.

      $i = 0;

      $ci = 0;

      $posizione = 0;//posizione all’interno della pagina

      //questa parte sarebbe meglio metterla in una funzione, in modo tale che se Google cambia il suo codice html basta modificare la funzione, il punto in azzurro serve per selezionare particolari punti dell’albero dom con la libreria simplehtmldom

      foreach($dom->find(‘div.g span.a’) as $node) {

        $posizione ++;

        if ( $trovato_risultato == 0 ) {

          $stringa_trasformata_risultato = $node->innertext;

          $controllo_risultato = strpos( str_replace(‘<b>’,”, str_replace(‘</b>’,”,$stringa_trasformata_risultato) ),$stringa_url);// tolgo <b> </b>

          $stringa_url_ripulita =  str_replace(‘<b>’,”, str_replace(‘</b>’,”,$stringa_trasformata_risultato) );

          if ( $controllo_risultato === FALSE ){

            echo “NON HO TROVATO IL RISULTATO<br>”;

          }

          else { //ho trovato la URL cercata

            $trovato_risultato = 1;

            $posizione_serp = $posizione + ($pagina_serp-1)*10;

            echo “TROVATO RISULTATO NELLA POSIZIONE: “. $posizione_serp.”<br>”;

          }

        }

      }//chiudo il ciclo foreach

      $node = NULL;

      unset($node);

      $secondi_attendere = rand(5,10);//aspetto un tempo casuale tra 5 e 10 secondi prima di andare alla prossima pagina della SERP

      sleep  (  $secondi_attendere );

      $dom->clear();

    }//fine ciclo tra le serp della pagina

    if ( $processare_query ){

      if ( $trovato_risultato == 0 ){

        $posizione_serp = 9999;//se non trovo il mio url nelle prime 9999 posizioni metto nel database comunque 9999

      }

    //inserisco nel database il risultato della ricerca

    $sql_insert_risultato = “INSERT INTO serp(query,rilevazione,posizione,urlserp) VALUES(‘”.$query.”‘,'”.$data_rilevazione.”‘,”.$posizione_serp.”,'”.$stringa_url_ripulita.”‘)”;

    mysql_query($sql_insert_risultato,$conn_database);

  }

  /************ FINE ANALISI DELLA QUERY IN ESAME  **********/

  $prelevo_time = time();

  $diff = $prelevo_time – $inizio_time;

  if ( $diff > 3300) { //55minuti = 3300 secondi -> Faccio durare lo script non più di 55 minuti

    mysql_close($conn_database);

    exit();

  }

  //tra una query e l’altra aspeto dai 60 ai 120 secondi, non posso prelevare troppe pagine da Google

    $secondi_attendere = rand(60,120);

    sleep  (  $secondi_attendere );

  } //Fine ciclo di tutte le query

  mysql_close($conn_database);

?>

Non mi dite che è difficile da capire, l’ho commentato tutto però se ci sono dubbi basta chiedere. Sicuramente lo script è migliorabile in molti punti però il suo sporco lavoro lo fa egregiamente 🙂 Dopo che l’avete fatto girare per un po’ di giorni non dovete fare altro che scaricare i dati dalla tabella serp e portarveli in un foglio Excel per farvi le vostre analisi. Vi allego uno screenshot di esempio della posizione delle mie query su Google (in ascissa si trova la data della rilevazione e nella ordinata si trova la posizione).

Screenshot di esempio

Questo è tutto amici. Se avete dubbi, volete creare qualche attività di business in Internet (siti web, forum,servizi online…) potete contattarmi su matteo.boffo@gmail.com. Ciao!!!