2011-11-27 34 views
12

Estoy tratando de analizar la tabla que se muestra here en una matriz php multidimensional. Estoy usando el siguiente código, pero por alguna razón devuelve una matriz vacía. Después de buscar en la web, encontré this site de donde obtuve la función parseTable(). Al leer los comentarios en ese sitio web, veo que la función funciona a la perfección. Así que supongo que hay algo mal con la forma en que recibo el código HTML de file_get_contents(). ¿Alguna idea de lo que estoy haciendo mal?Parse html table using file_get_contents to 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); 

?> 

Quiero que mi matriz de salida para buscar algo como esto:

 
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 por falta de esfuerzo. Aislar el problema en lugar de, básicamente, la publicación de un enorme bloque de código y preguntando a la gente a la figura repare lo que está mal y arréglelo. – NullUserException

Respuesta

43

No paralizar mismo análisis de HTML con expresiones regulares! En cambio, deje que una biblioteca de analizador de HTML se preocupe por la estructura del marcado para usted.

Sugiero que verifique HTML simple DOM (http://simplehtmldom.sourceforge.net/). Es una biblioteca específicamente escrita para ayudar a resolver este tipo de problemas de raspado web en PHP. Mediante el uso de dicha biblioteca, puede escribir su raspado en muchas menos líneas de códigos sin preocuparse por crear expresiones regulares de trabajo.

En principio, la simple HTML DOM que acaba de escribir algo como:

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

Esto puede ser luego se extendió a capturar los datos en un formato, por ejemplo, para crear una gran variedad de artistas y títulos correspondientes como:

<?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>'; 

?> 

podemos ver que este código puede ser (trivialmente) cambió a formatear los datos de cualquier otra manera también.

+0

Eso funcionó perfectamente. Pero necesito hacer una matriz multidimensional como se muestra en la parte inferior de la pregunta original. –

+0

¿Has echado un vistazo al ejemplo "Scraping Slashdot!" del sitio simplehtmldom? Por lo que yo entiendo, responde a esa pregunta. – jsalonen

+1

Ok, agregué otro ejemplo, pero esto es todo lo que voy a hacer. Dejaré el resto para que lo descubras. – jsalonen

17

Intenté simple_html_dom pero en archivos más grandes y en llamadas repetidas a la función estoy obteniendo zend_mm_heap_corrupted en php 5.3 (GAH). También probé preg_match_all (pero esto ha fallado en un archivo más grande (5000) líneas de html, que eran solo unas 400 filas de mi tabla HTML.

Estoy usando esto y está trabajando rápido y sin escupir errores.

$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); 

Este código ha funcionado bien para mí. Ejemplo de código original está aquí.

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

+1

sí, está trabajando para mí! :) :) –

+0

debe hacer array_shift ($ table) porque el primer elemento será [0] => array (0) { } vacío.es porque obtienes todas las etiquetas tr en $ filas, incluida la que tiene etiquetas th. Sugeriré una edición. –

+0

Estoy usando DOM con PHP 5.6.31, pero encontré que el resultado de '$ rows = $ tables-> item (0) -> getElementsByTagName ('tr')' no contiene ninguna etiqueta '' para un 'siguiente $ cols = $ row-> getElementsByTagName ('td') '. ¿Alguna idea de por qué mi primera llamada a 'getElementsByTagName()' parece quitar las etiquetas HTML? – Tony