2016-12-17 1 views
0

Je récupère du code HTML à partir d'un site Web avec file_get_contents. J'ai une table (avec un nom de classe) à l'intérieur de html, et je veux obtenir les données à l'intérieur des balises html.Obtention d'éléments DOM de html à partir de file_get_contents

Voilà comment je récupérer les données html depuis l'URL:

$url = 'http://example.com'; 
$content = file_get_contents($url); 

Le html ressemble:

<table class="space"> 
    <thead></thead> 
    <tbody> 
     <tr> 
     <td class="marsia">1</td> 
     <td class="mars"> 
      <div>Mars</div> 
     </td> 
     </tr> 
     <tr> 
     <td class="earthia">2</td> 
     <td class="earth"> 
      <div>Earth</div> 
     </td> 
     </tr> 
    </body> 
</table> 

est-il un moyen de searh éléments DOM en php comme nous le faisons en jQuery? Alors que je peux accéder aux valeurs 1, 2 (premier td) et la valeur de div à l'intérieur du deuxième td.

Quelque chose comme

a) recherche le code html pour la table avec un espace de nom de classe

b) à l'intérieur de cette table, à l'intérieur tbody, le retour de première valeur de td 'et 'la valeur de div à l'intérieur seconde td' de chacun des tr

Donc, je reçois; 1 et Mars, 2 et la Terre.

+0

Utilisez [DOMDocument] (http://php.net/manual/en/class.domdocument.php) pour analyser le code HTML. – Barmar

Répondre

0

Utilisez le DOM extension, par exemple. Sa classe DOMXPath est particulièrement utile pour ce genre de tâches.

Vous pouvez facilement définir les conditions énumérées avec une expression XPath comme ceci:

//table[@class="space"]//tr[count(td) = 2]/td 

où - //table[@class="space"] sélectionne tous les éléments table du document ayant class valeur d'attribut égale à "space" chaîne; - //tr[count(td) = 2] sélectionne tous les éléments tr ayant exactement deux éléments enfants td; - /td représente les éléments td.

exemple d'implémentation:

$html = <<<'HTML' 
<table class="space"> 
    <thead></thead> 
    <tbody> 
     <tr> 
     <td class="marsia">1</td> 
     <td class="mars"> 
      <div>Mars</div> 
     </td> 
     </tr> 
     <tr> 
     <td class="earthia">2</td> 
     <td class="earth"> 
      <div>Earth</div> 
     </td> 
     </tr> 
     <tr> 
     <td class="earthia">3</td> 
     </tr> 
    </tbody> 
</table> 
HTML; 

$doc = new DOMDocument; 
$doc->loadHTML($html); 

$xpath = new DOMXPath($doc); 

$cells = $xpath->query('//table[@class="space"]//tr[count(td) = 2]/td'); 

$i = 0; 
foreach ($cells as $td) { 
    if (++$i % 2) { 
    $number = $td->nodeValue; 
    } else { 
    $planet = trim($td->textContent); 
    printf("%d: %s\n", $number, $planet); 
    } 
} 

Sortie

1: Mars 
2: Earth 

Le code ci-dessus est censé être considéré comme un échantillon plutôt que d'une instruction pour une utilisation pratique, comme n'est pas très évolutif. La logique est liée au fait que l'expression XPath sélectionne exactement deux cellules pour chaque ligne. Dans la pratique, vous pouvez sélectionner les lignes, itérer les et mettre les conditions supplémentaires dans la boucle, par exemple:

$rows = $xpath->query('//table[@class="space"]//tr'); 

foreach ($rows as $tr) { 
    $cells = $xpath->query('.//td', $tr); 

    if ($cells->length < 2) { 
    continue; 
    } 

    $number = $cells[0]->nodeValue; 
    $planet = trim($cells[1]->textContent); 
    printf("%d: %s\n", $number, $planet); 
} 

DOMXPath::query() est appelée avec une expression XPath par rapport à la ligne actuelle ($tr), puis vérifie si le DOMNodeList renvoyé contient au moins deux cellules. Le reste du code est trivial.


Vous pouvez également utiliser SimpleXML extension, qui prend également en charge XPath. Mais l'extension est beaucoup moins flexible par rapport à l'extension DOM.

Pour les documents volumineux, utilisez des extensions basées sur des analyseurs basés sur SAX tels que XMLReader.