PHP Scraping PHP

Stato
Discussione chiusa ad ulteriori risposte.

Lazzah

Utente Bronze
24 Settembre 2014
9
2
1
40
Ciao a tutti,
sto cercando di realizzare un estrattore di dati per crearmi un piccolo programmino in PHP che mi estrae dei dati(prezzi) e li inserisca in un file CSV.
Per adesso ho realizzato quanto segue basandomi su guide e sulle mie conoscenze di base:
PHP:
<?php
error_reporting(E_ERROR | E_PARSE);
ini_set('display_errors', '1');

$url = "http://www.trovaprezzi.it/categoria.aspx?libera=8806088483016";
$class_to_scrape="item_total_price";

$html = file_get_contents($url);
$document = new DOMDocument();
$document->loadHTML($html);
$selector = new DOMXPath($document);

$anchors = $selector->query("/html/body//div[@class='". $class_to_scrape ."']");
//Funzione che stampa a video i risultati
foreach ($anchors as $node) {
       
   $full_content = innerHTML($node);      
   echo "<br>".$full_content."<br>" ;
                                 
}          
      
function innerHTML(DOMNode $node)
{
  $doc = new DOMDocument();
  foreach ($node->childNodes as $child) {
    $doc->appendChild($doc->importNode($child, true));
  }
  return $doc->saveHTML();
}

//Inserisce il risultato nel CSV ----- NON FUNZIONA
$file = fopen("file.csv","w");

foreach ($anchors as $node)
  {
  fputcsv($file, $list);
  }

fclose($file);  

?>

Non riesco però a capire come fare inserire i dati nel CSV, ed inoltre mi servirebbe che esegua un filtro per trovare il prezzo minore fra tutti quelli estrapolati.

Grazie a tutti quelli che proveranno ad aiutarmi! :)
 
Probabilmente l'errore è dovuto dal fatto che nell'ultimo foreach, dove inserisci i dati dentro il file csv, come secondo argomento della funzione specifichi una variabile che non ha mai dichiarato ($list), mentre dovresti inserire la variabile $node specificata nel foreach.

Per quanto riguarda il filtro per trovare il prezzo minore, dovresti innanzitutto convertire i valori dell'array in cui prelevi tutti i prezzi (essendo che si tratta di numeri) in intereger. Ma prima di questa operazione devi assicurarti che i valori degli array che darai in pasto alla conversione in intereger, devono essere stringhe composte unicamente da numeri (anche decimali) e quindi tutti eventuali caratteri come la moneta utilizzata, spazi, etc, devono essere rimossi prima di essere convertiti in int. Per farlo potresti fare una cosa del genere:
PHP:
$clean_anchors = array_map('trim', str_replace('€', '', $anchors));

Una volta assicurato che il tuo array sia composto unicamente da stringhe contenente numeri, converti i valori in intereger:
PHP:
$int_anchors = array_map('intval', $clean_anchors);

E infine, per trovare il valore minore nell'array usi la funzione min()
PHP:
$min_anchors = min($int_anchors);
 
  • Mi piace
Reazioni: killaemo
Ciao,
grazie per l'aiuto innanzitutto!
Andando per ordine, ho provato a modificare la funzione di inserimento dati nel CSV come da te indicato, sostituire variabile, però non ha creato alcuna modifica, il file rimane vuoto.
PHP:
$file = fopen("file.csv","w");

foreach ($anchors as $node)
  {
  fputcsv($file, $node);
  }

fclose($file);

Per quanto riguarda la funzione per trovare il valore minimo ho provato a fare quanto mi hai indicato ma senza risultato.
Sarà che non mi ricordo quasi più nulla di PHP, che ho studiato alle superiori o_O
L'unica cosa che mi ricordo è come realizzare siti/script a livello logico :oddio:

Ho inserito le 3 righe di codice da te fornite subito dopo la funzione che restituisce il valore $anchors, però il successivo output della variabile $min_anchors non stampa a video nulla.
Di seguito lo script completo:
PHP:
<?php
error_reporting(E_ERROR | E_PARSE);
ini_set('display_errors', '1');

$url = "http://www.trovaprezzi.it/categoria.aspx?libera=lg_f14u1jbs6";
$class_to_scrape="item_total_price";

$html = file_get_contents($url);
$document = new DOMDocument();
$document->loadHTML($html);
$selector = new DOMXPath($document);

$anchors = $selector->query("/html/body//div[@class='". $class_to_scrape ."']");
//Funzione che stampa a video i risultati

$clean_anchors = array_map('trim', str_replace('€', '', $anchors));
$int_anchors = array_map('intval', $clean_anchors);
$min_anchors = min($int_anchors);
echo "<br> Valore minimo: <br>";
echo $min_anchors ;

foreach ($anchors as $node) {
     
   $full_content = innerHTML($node);    
   echo "<br>".$full_content."<br>" ;
                                 
}     
      
function innerHTML(DOMNode $node)
{
  $doc = new DOMDocument();
  foreach ($node->childNodes as $child) {
    $doc->appendChild($doc->importNode($child, true));
  }
  return $doc->saveHTML();
}

//Inserisce il risultato nel CSV ----- NON FUNZIONA
$file = fopen("file.csv","w");

foreach ($anchors as $node)
  {
  fputcsv($file, $node);
  }

fclose($file);

?>
 
PHP:
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

$url = "http://www.trovaprezzi.it/categoria.aspx?libera=lg_f14u1jbs6";
$class_to_scrape = "item_total_price";

$html = file_get_contents($url);
$dom = new DOMDocument('1.0', 'UTF-8');
// http://stackoverflow.com/questions/1685277/warning-domdocumentloadhtml-htmlparseentityref-expecting-in-entity
$internalErrors = libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_use_internal_errors($internalErrors);

$xpath = new DOMXPath($dom);
$nodes = $xpath->query("/html/body//div[@class='{$class_to_scrape}']");

// Converte l'object in un array per poterlo leggere
$anchors = array();
foreach ($nodes as $node) {
    $anchors[] = $node->textContent;
}

$clean_anchors = array_map('trim', str_replace('Tot.', '', $anchors)); // Rimuove la scritta Tot. 
$int_anchors = array_map('intval', $clean_anchors); // Converte in intereger i numeri
$min_anchors = min($int_anchors); // Ricava il valore minimo dall'array pulito
echo "<br>Valore minimo:<br>{$min_anchors}";

// non c'è bisogno di fare il foreach, al secondo argument della funzione fputcsv devi dargli un array 
$file = fopen("file.csv", "w");
fputcsv($file, $clean_anchors);
fclose($file);

Prova questo, ti ho commentato i passaggi
 
  • Mi piace
Reazioni: Lazzah
Stato
Discussione chiusa ad ulteriori risposte.