Questione di array.. I risultato del foreach non è quello che voglio..

  • Creatore Discussione Creatore Discussione otto9due
  • Data di inizio Data di inizio

otto9due

Utente Attivo
22 Feb 2014
591
25
28
In breve ho scritto un piccolo parser dom per html che mi va a parsare alcune pagine amazon che mi interessano..
Il problema è che alla fine vorrei ottenere ( come si può vedere dall'echo in basso al codice sotto ) un risultato unitario per ogni prodotto.. Con titolo, link, imm ecc.. Invece attualmente appaiono così..

linklinklinklinklinktitolotitolotitolotitolo...ecc.
Posto il codice per com' è ora, già funzionante, effettua il parsing, come si può vedere scorrendo la pag dei risultati che ne deriva.. Qualcuno sa dirmi in cosa sbaglio? Sto uscendo pazzo!
PHP:
<?php 

$html = file_get_contents('http://www.amazon.it/s/ref=sr_il_to_luggage?rh=n%3A2454148031%2Cp_8%3A45-100&sort=relevancerank&ie=UTF8&qid=1430756991&lo=none');
$dom = new DOMDocument();
@$dom->loadHTML($html);

$xpath = new DOMXpath($dom);

$prodotti = array();

		// Link Prodotto
		$links = $xpath->query('//a[@class="a-link-normal a-text-normal"]');
		
		foreach ($links as $link) {
				$linkprod = $link->getAttribute('href');
				$prodotti[] = array( "linkprod" => $linkprod );
		}
		
		// Link immagine 
		$images = $xpath->query('//img[@alt="Dettagli prodotto"]');
		
		foreach ($images as $image) {
				$linkimm = $image->getAttribute('src');
				$prodotti[] = array( "images" => $linkimm );
		}
		
		// Nome prodotto 
		$titles = $xpath->query('//h2[@class="a-size-base a-color-null s-inline s-access-title a-text-normal"]');
		
		foreach ($titles as $title) {
				$titleprod = $title->nodeValue;
				$prodotti[] = array( "titolo" => $titleprod );
		}
		
		//Prezzo prima 
		$prezzops = $xpath->query('//span[@class="a-size-small a-color-secondary a-text-strike"]');
		
		foreach ($prezzops as $prezzop) {
				preg_match_all('/((\d{1,5}),(\d{2}))/', $prezzop->nodeValue , $res );
				$prezzoprima = $res[1][0];
				$prodotti[] = array( "prezzop" => $prezzoprima );
		}
		
		//Prezzo dopo 
		$prezzods = $xpath->query('//span[@class="a-size-base a-color-price s-price a-text-bold"]');
		
		foreach ($prezzods as $prezzod) {
				preg_match_all('/((\d{1,5}),(\d{2}))/', $prezzod->nodeValue , $res1 );
				$prezzodopo = $res1[1][0];
				$prodotti[] = array( "prezzodopo" => $prezzodopo );
		
		}


foreach ($prodotti as $prodotto):
			   	echo '<a href="'.$prodotto["linkprod"].'">'.$prodotto["titolo"].'</a><br>
				<img src="'.$prodotto["images"].'" alt="test" height="150" width="150"><br>
				Prima costava: '.$prodotto["prezzop"].' , ora viene: '.$prodotto["prezzodopo"].'';
endforeach;

?>

Basta incollare il codice salvarlo e caricarlo da qualche parte e funziona..
Unica cosa che ho notato è che all'interno di $linkprod come delle altre variabili simili, se le metto in un var_dump mi da solo il primo titolo, se faccio un echo mi da tutti i risultati appiccicati.. mha..
 
c'è qualche problema di sincronismo, vai avanti tu
ciao
Marino
PHP:
<?php 

$html = file_get_contents('http://www.amazon.it/s/ref=sr_il_to_luggage?rh=n%3A2454148031%2Cp_8%3A45-100&sort=relevancerank&ie=UTF8&qid=1430756991&lo=none');
$dom = new DOMDocument();
@$dom->loadHTML($html);

$xpath = new DOMXpath($dom);

$prodotti = array();
$prodotti["linkprod"]   = array();
$prodotti["images"]     = array();
$prodotti["titolo"]     = array();
$prodotti["prezzop"]    = array();
$prodotti["prezzodopo"] = array();

$i = 0;
$linkprod_prev = "";

	$links = $xpath->query('//a[@class="a-link-normal a-text-normal"]');
	foreach ($links as $link) {
		$linkprod = $link->getAttribute('href');
		if($linkprod_prev != $linkprod) {
			$prodotti["linkprod"][] = $linkprod;
			$i++;
		}
		$linkprod_prev = $linkprod;
	}
print_r ($prodotti["linkprod"]); print '<br /><br />';

	$images = $xpath->query('//img[@alt="Dettagli prodotto"]');
	foreach ($images as $image) {
		$linkimm = $image->getAttribute('src');
		$prodotti["images"][] = $linkimm;
	}
print_r ($prodotti["images"]); print '<br /><br />';

	$titles = $xpath->query('//h2[@class="a-size-base a-color-null s-inline s-access-title a-text-normal"]');
	foreach ($titles as $title) {
		$titleprod = $title->nodeValue;
		$prodotti["titolo"][] = $titleprod;
	}
print_r ($prodotti["titolo"]); print '<br /><br />';

	$prezzops = $xpath->query('//span[@class="a-size-small a-color-secondary a-text-strike"]');
	foreach ($prezzops as $prezzop) {
		preg_match_all('/((\d{1,5}),(\d{2}))/', $prezzop->nodeValue , $res );
		$prezzoprima = $res[1][0];
		$prodotti["prezzop"][] = $prezzoprima;
	}
print_r ($prodotti["prezzop"]); print '<br /><br />';

	$prezzods = $xpath->query('//span[@class="a-size-base a-color-price s-price a-text-bold"]');
	foreach ($prezzods as $prezzod) {
		preg_match_all('/((\d{1,5}),(\d{2}))/', $prezzod->nodeValue , $res1 );
		$prezzodopo = $res1[1][0];
		$prodotti["prezzodopo"][] = $prezzodopo;
	}
print_r ($prodotti["prezzodopo"]); print '<br /><br />';

for ($j=0; $j<$i; $j++)
		echo '<a href="'.$prodotti["linkprod"][$j].'">'.$prodotti["titolo"][$j].'</a><br>
		<img src="'.$prodotti["images"][$j].'" alt="test" height="150" width="150"><br>
		Prima costava: '.$prodotti["prezzop"][$j].' , ora viene: '.$prodotti["prezzodopo"][$j].'<br /><br />';
?>
 
Anzitutto ti ringrazio per l'aiuto, finalmente funziona, ma per completezza devo capire..
Ottima l'idea di utilizzare il for per aumentare l'indice dell'array, ma mi perdo un sec su questo costrutto e sulla sua funzione..
PHP:
$linkprod = $link->getAttribute('href');
        if($linkprod_prev != $linkprod) {
            $prodotti["linkprod"][] = $linkprod;
            $i++;
        }
        $linkprod_prev = $linkprod;

IN pratica gli stai chiedendo..se $linkprod_prev a cui inizialmente hai dato valore "" vuoto, è diverso da $linkprod ( che contiene i link giusto, tutti i link? ) Boo qui mi sono perso.. Mi spieghi un sec come funziona la cosa? Grazie
 
IN pratica gli stai chiedendo..se $linkprod_prev a cui inizialmente hai dato valore "" vuoto, è diverso da $linkprod ( che contiene i link giusto, tutti i link? ) Boo qui mi sono perso.. Mi spieghi un sec come funziona la cosa? Grazie

lavorando sul tuo codice ho notato che ci sono disallineamenti nella lettura delle parti, componenti della pagina.
in particolare il link dei prodotti era duplicato, quindi per vedere il funzionamento, ho inserito il controllo ovvero dei due link uguali, scarta il secondo
in questo modo si allineano le immagini e i testi, non i prezzi (precedenti e attuali)
credo che dovrai trovare un modo "più robusto" per estrarre le informazioni che ti servono,
ovvero identificare ciascun oggetto ed estrarre le sue info, con il sistema che hai postato non c'è certezza di associare il prezzo al suo componente (guarda la stampa delle array, in particolare il numero degli oggetti estratti per ciascuna di esse)
ciao
Marino
 
Ultima modifica:
Ora ho capito, grazie per la pazienza.. Grazie ai tuoi consigli e a quelli di altri amici, alla fine ho fatto così, per essere certo che tutto corrisponda, ho ciclato un div contenitore e riempito l'array man mano che ciclava.. ecco il risultato funzionante, lo posto dovesse servire a qualcuno..

PHP:
<?PHP
$html = file_get_contents('http://www.amazon.it/s/ref=sr_il_to_luggage?rh=n%3A2454148031%2Cp_8%3A45-100&sort=relevancerank&ie=UTF8&qid=1430756991&lo=none');
$dom = new DOMDocument();
@$dom->loadHTML($html);

$xpath = new DOMXpath($dom);

  // Cerco il div
  $divs = $xpath->query('//div[@class="s-item-container"]');

  // Inizializzo Array
  $dati_prodotto = array();
  
  // Primo ciclo per i div, entro nel nodo div
  foreach($divs as $div) {
	  	// Con il .// cerco all'interno del $div passato in query come secondo parametro.
		// Link Prodotto
        $links = $xpath->query('.//a[@class="a-link-normal a-text-normal"]', $div);
        
        foreach ($links as $link) {
                $linkprod = $link->getAttribute('href');
        }
        
        // Link immagine 
        $images = $xpath->query('.//img[@alt="Dettagli prodotto"]', $div);
        
        foreach ($images as $image) {
                $linkimm = $image->getAttribute('src');
        }
        
        // Nome prodotto 
        $titles = $xpath->query('.//h2[@class="a-size-base a-color-null s-inline s-access-title a-text-normal"]', $div);
        
        foreach ($titles as $title) {
                $titleprod = $title->nodeValue;
        }
        
        //Prezzo prima 
        $prezzops = $xpath->query('.//span[@class="a-size-small a-color-secondary a-text-strike"]', $div);
        
        foreach ($prezzops as $prezzop) {
                preg_match_all('/((\d{1,5}),(\d{2}))/', $prezzop->nodeValue , $res );
                $prezzoprima = $res[1][0];
        }
        
        //Prezzo dopo 
        $prezzods = $xpath->query('.//span[@class="a-size-base a-color-price s-price a-text-bold"]', $div);
        
        foreach ($prezzods as $prezzod) {
                preg_match_all('/((\d{1,5}),(\d{2}))/', $prezzod->nodeValue , $res1 );
                $prezzodopo = $res1[1][0];
        
        }
  
  //Creo un array per ogni fine ciclo div
  $dati_prodotto[] = array('linkprod' => $linkprod, 'imm' => $linkimm, 'titolo' => $titleprod, 'prezzop' => $prezzoprima, 'prezzodopo' => $prezzodopo );


  }// fine ciclo div

  
		foreach ($dati_prodotto as $singolo_prodotto) :
 		echo '<a href="'.$singolo_prodotto["linkprod"].'">'.$singolo_prodotto["titolo"].'</a><br>
        <img src="'.$singolo_prodotto["imm"].'" alt="test" height="150" width="150"><br>
        Prima costava: '.$singolo_prodotto["prezzop"].' , ora viene: '.$singolo_prodotto["prezzodopo"].'<br /><br />';
		endforeach;
?>

Grazie a tutti coloro che hanno partecipato :fonzie:
 

Discussioni simili