2011-11-27 13 views
12

Sto cercando di analizzare la tabella mostrata here in un array php multidimensionale. Sto usando il seguente codice ma per qualche motivo restituisce un array vuoto. Dopo aver cercato sul web, ho trovato this site, da cui ho ricevuto la funzione parseTable(). Leggendo i commenti su quel sito, vedo che la funzione funziona perfettamente. Quindi presumo ci sia qualcosa di sbagliato nel modo in cui ottengo il codice HTML da file_get_contents(). Qualche idea su cosa sto facendo male?Analizzare la tabella html utilizzando file_get_contents su php array

<?php 

$data = file_get_contents('http://flow935.com/playlist/flowhis.HTM'); 

function parseTable($html) 
{ 
    // Find the table 
    preg_match("/<table.*?>.*?<\/[\s]*table>/s", $html, $table_html); 

    // Get title for each row 
    preg_match_all("/<th.*?>(.*?)<\/[\s]*th>/", $table_html[0], $matches); 
    $row_headers = $matches[1]; 

    // Iterate each row 
    preg_match_all("/<tr.*?>(.*?)<\/[\s]*tr>/s", $table_html[0], $matches); 

    $table = array(); 

    foreach($matches[1] as $row_html) 
    { 
    preg_match_all("/<td.*?>(.*?)<\/[\s]*td>/", $row_html, $td_matches); 
    $row = array(); 
    for($i=0; $i<count($td_matches[1]); $i++) 
    { 
     $td = strip_tags(html_entity_decode($td_matches[1][$i])); 
     $row[$row_headers[$i]] = $td; 
    } 

    if(count($row) > 0) 
     $table[] = $row; 
    } 
    return $table; 
} 

$output = parseTable($data); 

print_r($output); 

?> 

voglio che il mio array di uscita a guardare qualcosa di simile:

 
1 
--> 11:33AM 
--> DEV 
--> IN THE DARK 

2 
--> 11:29AM 
--> LIL' WAYNE 
--> SHE WILL 

3 
--> 11:26AM 
--> KARDINAL OFFISHALL 
--> NUMBA 1 (TIDE IS HIGH) 
+1

-1 per mancanza di impegno. isolare il problema invece di fondamentalmente la pubblicazione di un enorme blocco di codice e chiedendo alla gente di fig Scopri cosa c'è che non va e risolvilo. – NullUserException

risposta

43

Non storpio da soli parsing HTML con espressioni regolari! Invece, lasciare che una libreria di parser HTML si preoccupi della struttura del markup per te.

Ti suggerisco di controllare Simple HTML DOM (http://simplehtmldom.sourceforge.net/). È una libreria appositamente scritta per aiutare a risolvere questo tipo di problemi di scraping web in PHP. Usando tale libreria, puoi scrivere il tuo scraping in meno linee di codice senza preoccuparti di creare espressioni regolari di lavoro.

In linea di principio, con i Simple HTML DOM basta scrivere qualcosa di simile:

$html = file_get_html('http://flow935.com/playlist/flowhis.HTM'); 
foreach($html->find('tr') as $row) { 
    // Parse table row here 
} 

Questo può essere poi esteso per catturare i dati in un formato, ad esempio per creare un array di artisti e titoli corrispondenti come:

<?php 
require('simple_html_dom.php'); 

$table = array(); 

$html = file_get_html('http://flow935.com/playlist/flowhis.HTM'); 
foreach($html->find('tr') as $row) { 
    $time = $row->find('td',0)->plaintext; 
    $artist = $row->find('td',1)->plaintext; 
    $title = $row->find('td',2)->plaintext; 

    $table[$artist][$title] = true; 
} 

echo '<pre>'; 
print_r($table); 
echo '</pre>'; 

?> 

possiamo vedere che questo codice può essere (banalmente) modificato per riformattare i dati in qualsiasi altro modo pure.

+0

Ha funzionato perfettamente. Ma ho bisogno di creare un array multidimensionale come mostrato nella parte inferiore della domanda originale. –

+0

Hai estratto l'esempio "Scraping Slashdot!" dal sito di simplehtmldom? Per quanto ho capito, rispondo a questa domanda. – jsalonen

+1

Ok ho aggiunto un altro esempio, ma questo è il massimo che farò. Lascerò il resto per te per capire. – jsalonen

17

Ho provato simple_html_dom ma su file più grandi e su chiamate ripetute alla funzione sto ottenendo zend_mm_heap_corrupted su php 5.3 (GAH). Ho anche provato preg_match_all (ma questo ha fallito su un file più grande (5000) linee di html, che erano solo circa 400 righe della mia tabella HTML

Sto usando questo e il suo funzionamento veloce e non sputa errori.

$dom = new DOMDocument(); 

//load the html 
$html = $dom->loadHTMLFile("htmltable.html"); 

    //discard white space 
$dom->preserveWhiteSpace = false; 

    //the table by its tag name 
$tables = $dom->getElementsByTagName('table'); 


    //get all rows from the table 
$rows = $tables->item(0)->getElementsByTagName('tr'); 
    // get each column by tag name 
$cols = $rows->item(0)->getElementsByTagName('th'); 
$row_headers = NULL; 
foreach ($cols as $node) { 
    //print $node->nodeValue."\n"; 
    $row_headers[] = $node->nodeValue; 
} 

$table = array(); 
    //get all rows from the table 
$rows = $tables->item(0)->getElementsByTagName('tr'); 
foreach ($rows as $row) 
{ 
    // get each column by tag name 
    $cols = $row->getElementsByTagName('td'); 
    $row = array(); 
    $i=0; 
    foreach ($cols as $node) { 
     # code... 
     //print $node->nodeValue."\n"; 
     if($row_headers==NULL) 
      $row[] = $node->nodeValue; 
     else 
      $row[$row_headers[$i]] = $node->nodeValue; 
     $i++; 
    } 
    $table[] = $row; 
} 

var_dump($table); 

Questo codice ha funzionato bene per me. Esempio di codice originale è qui.

http://techgossipz.blogspot.co.nz/2010/02/how-to-parse-html-using-dom-with-php.html

+1

si sta lavorando per me! :) :) –

+0

si dovrebbe fare array_shift ($ table) perché il primo elemento sarà [0] => array (0) { } vuoto.è perché ottieni tutti i tag tr in $ file incluso quello con i tag th. Suggerirò una modifica. –

+0

Sto usando DOM con PHP 5.6.31, ma ho trovato che il risultato di '$ rows = $ tables-> item (0) -> getElementsByTagName ('tr')' non contiene alcun '' 'tag per un successivo' $ cols = $ row-> getElementsByTagName ('td') '. Qualche idea sul perché la mia prima chiamata a 'getElementsByTagName()' sembra stia eliminando i tag HTML? – Tony