2010-08-04 7 views
6

Je suis « essaie » de gratter une page Web qui a les structures suivantes dans la page:Comment analyser HTML réel de la page en utilisant CURL?

<p class="row"> 
    <span>stuff here</span> 
    <a href="http://www.host.tld/file.html">Descriptive Link Text</a> 
    <div>Link Description Here</div> 
</p> 

Je racler la page Web en utilisant boucle:

<?php 
    $handle = curl_init(); 
    curl_setopt($handle, CURLOPT_URL, "http://www.host.tld/"); 
    curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); 
    $html = curl_exec($handle); 
    curl_close($handle); 
?> 

Je l'ai fait quelques recherches et trouvé que je ne devrais pas utiliser un RegEx pour analyser le HTML qui est retourné depuis le curl, et que je devrais utiliser PHP DOM. Voilà comment je l'ai fait:

$newDom = new domDocument; 
$newDom->loadHTML($html); 
$newDom->preserveWhiteSpace = false; 
$sections = $newDom->getElementsByTagName('p'); 
$nodeNo = $sections->length; 
for($i=0; $i<$nodeNo; $i++){ 
    $printString = $sections->item($i)->nodeValue; 
    echo $printString . "<br>"; 
} 

Maintenant, je ne prétends pas que je comprends tout à fait cela, mais je reçois l'essentiel, et je reçois les sections je manque. Le seul problème est que ce que je reçois est seulement le texte de la page HTML, comme si je l'avais copié hors de la fenêtre de mon navigateur. Ce que je veux le code HTML réel parce que je veux extraire les liens et les utiliser aussi comme ceci:

for($i=0; $i<$nodeNo; $i++){ 
    $printString = $sections->item($i)->nodeValue; 
    echo "<a href=\"<extracted link>\">LINK</a> " . $printString . "<br>"; 
} 

Comme vous pouvez le voir, je ne peux pas le lien car je ne reçois le texte du page Web et non la source de , comme je veux. Je sais que le « curl_exec » tire le code HTML parce que je l'ai essayé tout ça, donc je crois que le DOM est en quelque sorte le décapage HTML que je veux.

Répondre

4

Selon les commentaires sur the PHP manual on DOM, vous devez utiliser les éléments suivants dans votre boucle:

$tmp_dom = new DOMDocument(); 
    $tmp_dom->appendChild($tmp_dom->importNode($sections->item($i), true)); 
    $innerHTML = trim($tmp_dom->saveHTML()); 

Ceci règlera $innerHTML être le contenu HTML du nœud.

Mais je pense que ce que vous voulez vraiment est d'obtenir « a » nœuds sous le nœud « p », donc faire ceci:

$sections = $newDom->getElementsByTagName('p'); 
$nodeNo = $sections->length; 
for($i=0; $i<$nodeNo; $i++) { 
    $sec = $sections->item($i); 
    $links = $sec->getElementsByTagName('a'); 
    $linkNo = $links->length; 
    for ($j=0; $j<$linkNo; $j++) { 
     $printString = $links->item($j)->nodeValue; 
     echo $printString . "<br>"; 
    } 
} 

Cela suffit d'imprimer le corps de chaque lien.

+0

Vous pouvez également parcourir les noeuds en utilisant 'foreach' au lieu des boucles' for'. Cela le rendra plus compact et compréhensible, puisque vous n'avez (en fait) besoin d'aucun des indices. – janmoesen

0

vous pouvez jeter un oeil à phpQuery pour faire les choses côté serveur d'analyse syntaxique HTML. basic example

1

Vous pouvez passer un nœud à DOMDocument::saveXML(). Essayez ceci:

$printString = $newDom->saveXML($sections->item($i));

+0

Oui, ce sera de retour efficacement les 'outerHTML' du nœud – Gordon

+0

Apparemment, l'affiche voulait que le HTML intérieur, et non l'extérieur. Ce n'était pas clair pour moi, mais je vais laisser ma réponse pour la référence 'saveXML', de toute façon. – janmoesen

Questions connexes