Extracción de datos de HTML
Mucha gente trata de extraer el contenido de HTML – el primer enfoque siempre parece ser el uso de expresiones regulares, que son incapaces de analizar el código. Entonces, ¿cómo hacerlo bien con PHP?
Esto es bastante trivial e intuitivo de hacer – más simple que escribir expresiones regulares para la mayoría de la gente. PHP tiene esta fantástico extensión DOM, que se basa en libxml2 y no sólo puede trabajar con XML, sino también con HTML. Echemos un vistazo a un snippet para la extracción de todos los enlaces de una página web:
<?php $oldSetting = libxml_use_internal_errors( true ); libxml_clear_errors(); $html = new DOMDocument(); $html->loadHtmlFile( 'http://jmacoe.com/blog/test.html' ); $xpath = new DOMXPath( $html ); $links = $xpath->query( '//a' ); foreach ( $links as $link ) { echo $link->getAttribute( 'href' ), "\n"; } libxml_clear_errors(); libxml_use_internal_errors( $oldSetting ); ?>
Eso es todo, y trabaja también para sitios web que no pasan los validadores, pero arroja un montón de errores. La función libxml_use_internal_errors (true) le dice al libxml que no exponga las advertencias y los errores a través del sistema de reporte de errores del PHP, pero las almacena internamente. Todos los errores de validación se pueden solicitar más adelante mediante la función libxml_get_errors(). También podemos limpiar los errores producidos, de esta manera obtenemos una nueva lista limpia – si algo pasó antes.
A continuación, sólo puedes cargar el archivo HTML, usando los métodos especiales loadHtml() o loadHtmlFile(). Normalmente, debes utilizar la última, ya que la detección de codificación funciona mucho mejor. Estos métodos pueden controlar y corregir muchos errores comunes que se realizan en el marcado HTML y devolver una representación XML limpia.
Después de que puedes consultar el contenido del documento HTML usando XPath (Toby y Jakob acaba de publicar una guía completa y buena XPath). Y en la mayoría de los casos, ni siquiera se necesita cualquier consulta XPath compleja, pero sí un «//a» o similar realizara el trabajo.
El DOMNodeList devuelto es implementado a través de varias versiones, por lo que sólo puede iterar sobre él, usando foreach y realizar el procesamiento después. Y al final siempre se debe restablecer el reporte de error libxml al estado original para no meterse con otras partes de la aplicación.
Este ejemplo imprime la lista con todos los enlaces del documento HTML analizado, sin expresiones regulares complejas (que no siempre hacen lo correcto – nunca – esta desmotrado – creanme), sino una consulta XPath trivial.
Recuerda que no todos los sitios web permiten copiar su contenido. Esto podría violar sus términos de servicio o fácilmente pueden violar los derechos de autor al incrustar contenidos copiados en tu aplicación. Utilizo con precaución.
Entradas relacionadas