PHP: crawleando los ficheros de imágenes, CSS y Javascripts de una página

Hoy traigo un pequeño CODE-KATA en PHP para iniciar el crawleo de una página web. Se trata de un pequeño script en PHP con el que listar lo que llamamos assets de una página.

Los assets de una página son los ficheros de imágenes, CSS y Javascript que una página web usa para que tenga buena pinta. Por otro lado tenemos que los datos de una página web se estructuran en un objeto que se llama DOM. Este DOM es el Document Object Model, es un estándar, y también es el estándar de arranque que se usa desde los inicios de la web. El DOM se usa para que tanto servidores como navegadores se entiendan, también para la intercomunicación de sistemas informáticos, guardado de datos, y muchas cosas más.. pero para lo que vengo a escribir, me voy a centrar sólo en las webs.

Cómo cargar el DOM de una página web de inicio en PHP

<?php
$dom = new DOMDocument();
@$dom->loadHTMLFile('https://jnjsite.com/');

Sencillo ¿verdad? Con ésto ya tenemos en la variable $dom la página de inicio de ésta web. Lo siguiente que podemos hacer es un var_dump del DOM para ver qué es lo que hay, añadimos ésta línea:

var_dump($dom);

Escribimos éstos códigos de arriba en un fichero llamado por ejemplo test.php y ejecutamos esto desde línea de comandos:

php test.php

Y veremos lo siguiente:

/home/jaime/Descargas/test.php:7:
class DOMDocument#1 (35) {
public $doctype =>
string(22) "(object value omitted)"
public $implementation =>
string(22) "(object value omitted)"
public $documentElement =>
string(22) "(object value omitted)"
public $actualEncoding =>
string(5) "UTF-8"
public $encoding =>
string(5) "UTF-8"
public $xmlEncoding =>
string(5) "UTF-8"
public $standalone =>
bool(true)
public $xmlStandalone =>
bool(true)
public $version =>
NULL
public $xmlVersion =>
NULL
public $strictErrorChecking =>
bool(true)
public $documentURI =>
string(20) "https://jnjsite.com/"
public $config =>
NULL
public $formatOutput =>
bool(false)
public $validateOnParse =>
bool(false)
public $resolveExternals =>
bool(false)
public $preserveWhiteSpace =>
bool(true)
public $recover =>
bool(false)
public $substituteEntities =>
bool(false)
public $nodeName =>
string(9) "#document"
public $nodeValue =>
NULL
public $nodeType =>
int(13)
public $parentNode =>
NULL
public $childNodes =>
string(22) "(object value omitted)"
public $firstChild =>
string(22) "(object value omitted)"
public $lastChild =>
string(22) "(object value omitted)"
public $previousSibling =>
NULL
public $nextSibling =>
NULL
public $attributes =>
NULL
public $ownerDocument =>
NULL
public $namespaceURI =>
NULL
public $prefix =>
string(0) ""
public $localName =>
NULL
public $baseURI =>
NULL
public $textContent =>
string(25762) "(function(html){html.className = html.className.replace(/\bno-js\b/,'js')})(document.documentElement);JnjSite.com • Entre bastidores de un apasionado de la informáticafunction theChampLoadEvent(e){var t=window.onload;if(typeof window.onload!="function"){window.onload=e}else{window.onload=function(){t();e()}}}var theChampDefaultLang = 'es_ES', theChampCloseIconPath = 'https://jnjsite.com/wp-content/plugins/super-socializer/images/close.png';var heateorSsSDKBlockedMsg = `Your browser is blocking some featu"…
}

Ya tenemos toda la página de inicio cargada en un DOMDocument de PHP. Ésta es la clase que nos proporciona PHP para manejar las webs y viene incorporada dentro del lenguaje.

Navegando por los nodos

Hay que saber que todo dentro de un DOM es un árbol. Tenemos un nodo raíz del que parten las ramas hijas, o nodos hijos, que serán de varios tipos, y así sucesivamente.. tal y como veríamos en un tutorial sobre HTML.

Lo siguiente es para listar las imágenes:

$cont = 0;
foreach ($dom->getElementsByTagName('img') as $imageNode) {
++$cont;
echo 'Image '.$cont.PHP_EOL;
//var_dump($imageNode);

foreach ($imageNode->attributes as $attribute) {
//var_dump($attribute);
echo ' '.$attribute->name.': '.$attribute->value.PHP_EOL;
}
}

Fíjate que marco en negrita cómo sacar un listado de todos los nodos que son imágenes. Es decir, tan simple como decirle al objeto $dom que nos de todos los elementos con la etiqueta de tipo img.

Lo mismo podríamos hacer para los nodos que enlazan a ficheros CSS:

$cont = 0;
foreach ($dom->getElementsByTagName('link') as $imageNode) {
++$cont;
echo 'Link '.$cont.PHP_EOL;
//var_dump($imageNode);

foreach ($imageNode->attributes as $attribute) {
//var_dump($attribute);
echo ' '.$attribute->name.': '.$attribute->value.PHP_EOL;
}
}

Y para los nodos de Javascripts:

$cont = 0;
foreach ($dom->getElementsByTagName('script') as $imageNode) {
++$cont;
echo 'Script '.$cont.PHP_EOL;
//var_dump($imageNode);
foreach ($imageNode->attributes as $attribute) {
//var_dump($attribute);
echo ' '.$attribute->name.': '.$attribute->value.PHP_EOL;
}
}

Recordemos que buscamos para las hojas de estilo que están en ficheros los nodos de tipo <link> que son los que enlazan con el atributo href= al fichero externo de CSS. Lo mismo pasa con los Javascripts que son los nodos de tipo <script> pero que nos dicen el fichero Javascript enlazado desde el documento con su atributo src=

Recapitulando, sacando el listado final de assets de una página web

Cogiendo todos los códigos anteriores, reunidos y modificados para sólo listar la información que buscamos, tendremos lo siguiente:

 <?php

$dom = new DOMDocument();
$thePage = 'https://jnjsite.com/';
@$dom->loadHTMLFile($thePage);

echo 'Assets de la página web: '.$thePage.PHP_EOL;
$cont = 0;
foreach ($dom->getElementsByTagName('img') as $imageNode) {
++$cont;
foreach ($imageNode->attributes as $attribute) {
if ('src' == $attribute->name) {
echo 'Image '.$cont.': '.$attribute->value.PHP_EOL;
}
}
}

foreach ($dom->getElementsByTagName('link') as $imageNode) {
++$cont;
foreach ($imageNode->attributes as $attribute) {
if ('href' == $attribute->name) {
echo 'CSS '.$cont.': '.$attribute->value.PHP_EOL;
}
}
}

foreach ($dom->getElementsByTagName('script') as $imageNode) {
++$cont;
foreach ($imageNode->attributes as $attribute) {
if ('src' == $attribute->name) {
echo 'Script '.$cont.': '.$attribute->value.PHP_EOL;
}
}
}

Terminando

Fíjate que con el último código te lista todos los valores de atributos, sólo le faltaría el comprobar unas cosas, porque el listado real de assets será menor.

Para las imágenes, tendremos que comprobar que la imagen puede estar en el src o en el data-src, según si algún Javascript posteriormente te lo sirve. Aunque originalmente debiera de estar en src.

Para los CSS, hay que comprobar el atributo rel sea igual a stylesheet. Esto nos indicará que tendremos en el href tendremos dicho fichero externo, sino será otra cosa.

Y finalmente para los Javascripts, directamente si tenemos un atributo src, éste tendrá la dirección del fichero asset de Javascript que buscamos.

Me remito a la documentación oficial de PHP para más información sobre el DOMDocument: http://php.net/manual/es/book.dom.php

Compartir..

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *