Accediendo al DOM HTML con PHP
- Andrés Cruz
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.
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
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter