2010-08-04 4 views
6

estoy "tratando" para raspar una página web que tiene las siguientes estructuras dentro de la página:¿Cómo se analiza el HTML real de la página con 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> 

estoy raspando la página web utilizando rizo:

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

he hecho algunas investigaciones y encontró que no debería usar un RegEx para analizar el HTML que se devuelve desde el curl, y que debería usar PHP DOM. Así es como yo he hecho esto:

$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>"; 
} 

Ahora no pretendo que entiendo completamente esto, pero me da la esencia, y me pongo las secciones que estoy queriendo. El único problema es que lo que obtengo es solo el texto de la página HTML, como si lo hubiera copiado fuera de la ventana de mi navegador. Lo que quiero es el HTML real porque quiero extraer los enlaces y las uso también, de este modo:

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

Como se puede ver, no puedo obtener el enlace porque yo sólo estoy recibiendo el texto de la página web y no fuente, como yo quiero. Sé que "curl_exec" está extrayendo el HTML porque ya lo intenté, así que creo que DOM está de alguna manera eliminando el HTML que quiero.

Respuesta

4

De acuerdo con los comentarios sobre the PHP manual on DOM, se debe utilizar la siguiente dentro de su bucle:

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

Esto establecerá $innerHTML ser el contenido HTML del nodo.

pero creo que lo que realmente quiere es conseguir que los nodos 'a' en el nodo 'p', así que esto:

$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>"; 
    } 
} 

esto sólo imprimir el cuerpo de cada enlace.

+0

También se pueden recorrer a través de los nodos usando 'foreach' en lugar de los bucles' for'. Eso lo hará más compacto y comprensible, ya que no necesita (parece) ninguno de los índices. – janmoesen

0

es posible que desee echar un vistazo a phpQuery para hacer cosas de análisis de HTML del lado del servidor. basic example

1

Puede pasar un nodo a DOMDocument::saveXML(). Prueba esto:

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

+0

Sí, esto devolverá efectivamente el 'outerHTML' del nodo – Gordon

+0

Aparentemente, el póster quería el HTML interno, no el externo. Eso no estaba claro para mí, pero dejaré mi respuesta para la referencia 'saveXML', de todos modos. – janmoesen

Cuestiones relacionadas