web-dev-qa-db-fra.com

Analyser la table html en utilisant file_get_contents vers le tableau php

J'essaie d'analyser le tableau montré ici dans un tableau php multidimensionnel. J'utilise le code suivant, mais pour une raison quelconque, il renvoie un tableau vide. Après avoir fait des recherches sur le Web, j'ai trouvé ce site d'où je tire la fonction parseTable (). En lisant les commentaires sur ce site, je constate que la fonction fonctionne parfaitement. Je suppose donc qu'il y a un problème avec la façon dont j'obtiens le code HTML de file_get_contents (). Des pensées sur ce que je fais mal?

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

?>

Je veux que mon tableau de sortie ressemble à ceci:

 1 
 -> 11:33 AM 
 -> DEV 
 -> DANS L'OBSCURITÉ 
 
 2 
 -> 11:29 AM 
 -> LIL 'WAYNE 
 -> ELLE VA 
 
 3 
 -> 11 : 26AM 
 -> KARDINAL OFFISHALL 
 -> NUMBA 1 (TIDE IS HIGH) 
13
Farhan Ahmad

Ne vous paralysez pas en analysant HTML avec des expressions régulières! Au lieu de cela, laissez une bibliothèque d'analyseur HTML s'inquiéter de la structure du balisage pour vous.

Je vous suggère de vérifier Simple HTML DOM ( http://simplehtmldom.sourceforge.net/ ). Il s'agit d'une bibliothèque spécialement conçue pour aider à résoudre ce type de problèmes de grattage Web en PHP. En utilisant une telle bibliothèque, vous pouvez écrire votre scraping dans beaucoup moins de lignes de codes sans vous soucier de créer des expressions rationnelles fonctionnelles.

En principe, avec Simple HTML DOM, vous écrivez simplement quelque chose comme:

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

Cela peut ensuite être étendu pour capturer vos données dans un certain format, par exemple pour créer un tableau d'artistes et de titres correspondants comme:

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

?>

Nous pouvons voir que ce code peut être (trivialement) modifié pour reformater les données de toute autre manière également.

49
jsalonen

J'ai essayé simple_html_dom mais sur des fichiers plus gros et sur des appels répétés à la fonction, je reçois zend_mm_heap_corrupted sur php 5.3 (GAH). J'ai également essayé preg_match_all (mais cela a échoué sur un fichier plus grand (5000) lignes de html, qui ne représentait qu'environ 400 lignes de ma table HTML.

J'utilise ceci et son fonctionnement rapide et ne crache pas d'erreurs.

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

Ce code a bien fonctionné pour moi. Un exemple de code original est ici.

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

18
John Ballinger