Accediendo al DOM HTML con PHP

- Andrés Cruz

Accediendo al DOM HTML con PHP

En esta entrada veremos cómo acceder al DOM de una página web o contenido HTML con PHP; para esto haremos uso de la clase DOMDocument de PHP que nos permite realizar ciertas operaciones como las que hacemos con JavaScript empleando los selectores en la cual debemos especificar el número de la versión del documento, esto solo es un declaración y no tiene mayores repercusiones; el segundo parámetro corresponde a definir la codificación del contenido:

function getContent($url) {

    if (stripos($url, 'http') !== 0) {
        $url = 'http://' . $url;
    }
    $content = new DOMDocument('1.0', 'utf-8');
    $content->preserveWhiteSpace = FALSE;

    @$content->loadHTMLFile($url);
    return $content->getElementsByTagName('*');
}

Para esta función recibimos una URL en la cual validamos que esté presente la referencia al http, creamos un objeto de tipo DOMDocument para luego cargar el contenido HTML de nuestra URL con la función loadHTMLFile() en la cual le indicamos la URL del sitio a cargar; por último una función llamada a getElementsByTagName() que nos permite acceder al elemento que queramos, si es un párrafo p, h1, todos *, o cualquier tag conocido; a posterior, ya con los elementos seleccionados mediante nodos, podemos acceder a sus atributos y de esta manera podemos eliminar y/o secciones de código de una página en HTML desde PHP.

preserveWhiteSpace permite remover o no espacios en blanco redundantes. Predeterminado a TRUE.

Finalmente, el código anterior tendría una salida como la siguiente:

getContent("http://www.desarrollolibre.net/blog")

// *** salida
object(DOMNodeList)#2 (1) { ["length"]=> int(184) }

En este caso, la función nos retornaría una serie de nodos que luego podemos iterar con alguna ciclo como el foreach como veremos con el siguiente ejemplo.

Accediendo a los nodos

Luego que tengamos el contenido referenciado a través de los nodos, podemos acceder al contenido a gusto; por ejemplo, podemos acceder a sus atributos como hacemos en la siguiente función:

function getAttribute($url, $attr) {
    $result = array();
   
    $content = new DOMDocument('1.0', 'utf-8');
    $content->preserveWhiteSpace = FALSE;
    
    @$content->loadHTMLFile($url);
    $elements = $content
            ->getElementsByTagName('*');
    
    foreach ($elements as $node) {
        if ($node->hasAttribute($attr)) {
            $value = $node->getAttribute($attr);
            $result[] = trim($value);
        }
    }
    
    return $result;
}

Como puedes ver, en esta oportunidad iteramos los nodos, que a la final son cada unos de los tags que tengamos definidos, accedemos a alguno de sus atributos que pasaramos como uno de los parámetros en la firma de la función y los guardamos en un array; finalmente obtendremos algo como lo siguiente:

getAttribute("http://www.desarrollolibre.net/blog","class")

// *** salida
array(70) { [0]=> string(9) "logo_name" [1]=> string(4) "logo" [2]=> string(14) "logo_150_white" [3]=> string(4) "name" [4]=> string(13) "show_category" [5]=> string(15) "material-design" [6]=> string(19) "promotion col-md-12" [7]=> string(23) "col-md-4-p margin-1-p-p" [8]=> string(27) "card card1 white box-shadow" [9]=> string(15) "material-design" [10]=> string(23) "col-md-4-p margin-1-p-p" [11]=> string(27) "card card1 white box-shadow" [12]=> string(15) "material-design" [13]=> string(23) "col-md-4-p margin-1-p-p" [14]=> string(27) "card card1 white box-shadow" [15]=> string(15) "material-design" [16]=> string(10) "box-result" [17]=> string(14) "col-md-12 left" [18]=> string(22) "item-publication theme" [19]=> string(11) "rating-NULL" [20]=> string(4) "date" [21]=> string(9) "posted-on" [22]=> string(22) "item-publication theme" [23]=> string(11) "rating-NULL" [24]=> string(4) "date" [25]=> string(9) "posted-on" [26]=> string(29) "item-publication theme update" [27]=> string(11) "rating-NULL" [28]=> string(4) "date" [29]=> string(9) "posted-on" [30]=> string(3) "red" [31]=> string(14) "col-md-12 left" [32]=> string(22) "item-publication theme" [33]=> string(11) "rating-NULL" [34]=> string(4) "date" [35]=> string(9) "posted-on" [36]=> string(22) "item-publication theme" [37]=> string(11) "rating-NULL" [38]=> string(4) "date" [39]=> string(9) "posted-on" [40]=> string(22) "item-publication theme" [41]=> string(11) "rating-NULL" [42]=> string(4) "date" [43]=> string(9) "posted-on" [44]=> string(22) "item-publication theme" [45]=> string(11) "rating-NULL" [46]=> string(4) "date" [47]=> string(9) "posted-on" [48]=> string(14) "col-md-12 left" [49]=> string(22) "item-publication theme" [50]=> string(11) "rating-NULL" [51]=> string(4) "date" [52]=> string(9) "posted-on" [53]=> string(22) "item-publication theme" [54]=> string(11) "rating-NULL" [55]=> string(4) "date" [56]=> string(9) "posted-on" [57]=> string(22) "item-publication theme" [58]=> string(11) "rating-NULL" [59]=> string(4) "date" [60]=> string(9) "posted-on" [61]=> string(13) "show_category" [62]=> string(15) "material-design" [63]=> string(10) "pagination" [64]=> string(6) "active" [65]=> string(9) "next-link" [66]=> string(15) "scrollup fab_up" [67]=> string(22) "social-50 arrow_top_50" [68]=> string(19) "scrolldown fab_down" [69]=> string(25) "social-50 arrow_bottom_50" }

Podemos también incorporar código HTML en alguna posición en especifica; por ejemplo, luego del quinto nodo por decir alguna posición:

function createElement($url) {
    
    $content = new DOMDocument('1.0', 'utf-8');
    $content->preserveWhiteSpace = FALSE;

    @$content->loadHTMLFile($url);

    $ins = $content->createElement("ins", "***ESTO ES UN TAG AGREGADO CON PHP***");

    // agrega un elemento en la posición 5 posicion 5
    $content->getElementsByTagName('h2')->item(4)->appendChild($ins);

}

Para eso es la función appendChild() que recibe como parámetro un elemento creado mediante el método createElement() que permite crear un elemento (en este ejemplo se creó un elemento de tipo ins según el primer parámetro establecido, con el contenido de -***ESTO ES UN TAG AGREGADO CON PHP***-).

function deleteElement($url) {

    $content = new DOMDocument('1.0', 'utf-8');
    $content->preserveWhiteSpace = FALSE;

    @$content->loadHTMLFile($url);

    // eliminamos un elemento
    $h2 = $content->getElementsByTagName('h2')->item(0);
    $pnode = $h2->parentNode;
    $pnode->removeChild($h2);
}

Para eliminar un elemento, como mostramos en el código anterior con el primer h2 que exista en nuestra selección (para ello es la función item(0)), nos traemos el elemento padre del h2 con $h2->parentNode y luego eliminamos el h2 en cuestión con $pnode->removeChild($h2) empleando el elemento padre y como parámetro la referencia (el hijo) al h2.

Puedes revisar la documentación oficial en PHP DOMDocument

Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy

Acepto recibir anuncios de interes sobre este Blog.