¿Cómo se analiza y procesa HTML / XML en PHP?

¿Cómo se puede analizar HTML / XML y extraer información de él?

preguntado el 26 de agosto de 10 a las 18:08

30 Respuestas

Extensiones XML nativas

Prefiero usar uno de los extensiones XML nativas ya que vienen con PHP, generalmente son más rápidos que todas las bibliotecas de terceros y me brindan todo el control que necesito sobre el marcado.

DOM

La extensión DOM le permite operar en documentos XML a través de DOM API con PHP 5. Es una implementación del Document Object Model Core Level 3 del W3C, una interfaz neutral de plataforma y lenguaje que permite que los programas y scripts accedan y se actualicen dinámicamente. el contenido, la estructura y el estilo de los documentos.

DOM es capaz de analizar y modificar HTML del mundo real (roto) y puede hacer Consultas XPath. Está basado en libxml.

Se necesita algo de tiempo para ser productivo con DOM, pero ese tiempo bien vale la pena, en mi opinión. Dado que DOM es una interfaz independiente del lenguaje, encontrará implementaciones en muchos lenguajes, por lo que si necesita cambiar su lenguaje de programación, es probable que ya sepa cómo usar la API DOM de ese lenguaje.

Puede encontrar un ejemplo de uso básico en Tomando el atributo href de un elemento A y una descripción general conceptual se puede encontrar en DOMDocument en php

Cómo usar la extensión DOM se ha cubierto ampliamente en StackOverflow, por lo que si elige usarlo, puede estar seguro de que la mayoría de los problemas con los que se encuentra se pueden resolver buscando / navegando en Stack Overflow.

XMLReader

La extensión XMLReader es un analizador de extracción XML. El lector actúa como un cursor que avanza en el flujo de documentos y se detiene en cada nodo en el camino.

XMLReader, como DOM, se basa en libxml. No sé cómo activar el módulo de analizador de HTML, por lo que es probable que el uso de XMLReader para analizar HTML roto sea menos robusto que el uso de DOM, donde puede indicarle explícitamente que utilice el módulo de analizador de HTML de libxml.

Puede encontrar un ejemplo de uso básico en obteniendo todos los valores de las etiquetas h1 usando php

Analizador XML

Esta extensión le permite crear analizadores XML y luego definir controladores para diferentes eventos XML. Cada analizador XML también tiene algunos parámetros que puede ajustar.

La biblioteca XML Parser también se basa en libxml e implementa una SAX analizador push XML de estilo. Puede ser una mejor opción para la administración de memoria que DOM o SimpleXML, pero será más difícil trabajar con él que con el analizador de extracción implementado por XMLReader.

Simplexml

La extensión SimpleXML proporciona un conjunto de herramientas muy simple y fácil de usar para convertir XML en un objeto que se puede procesar con selectores de propiedades normales e iteradores de matriz.

SimpleXML es una opción cuando sabes que HTML es XHTML válido. Si necesita analizar HTML roto, ni siquiera considere SimpleXml porque se ahogará.

Puede encontrar un ejemplo de uso básico en Un programa simple para el nodo CRUD y los valores de nodo del archivo xml y hay muchos ejemplos adicionales en el manual de PHP.


Bibliotecas de terceros (basadas en libxml)

Si prefiere usar una biblioteca de terceros, le sugiero que use una biblioteca que realmente use DOM/libxml debajo en lugar de analizar cadenas.

FluentDom - Repo

FluentDOM proporciona una interfaz XML fluida similar a jQuery para DOMDocument en PHP. Los selectores están escritos en XPath o CSS (usando un conversor de CSS a XPath). Las versiones actuales amplían el DOM implementando interfaces estándar y agregan características del DOM Living Standard. FluentDOM puede cargar formatos como JSON, CSV, JsonML, RabbitFish y otros. Se puede instalar a través de Composer.

HtmlPageDom

Wa72 \ HtmlPageDom` es una biblioteca PHP para una fácil manipulación de documentos HTML usando Requiere DomCrawler de Symfony2 componentes para atravesar el árbol DOM y lo amplía agregando métodos para manipular el árbol DOM de documentos HTML.

phpQuery (no actualizado desde hace años)

phpQuery es una API de Modelo de Objetos de Documento (DOM) del lado del servidor, encadenable, impulsada por selector CSS3 basada en la biblioteca jQuery JavaScript escrita en PHP5 y proporciona una interfaz de línea de comandos (CLI) adicional.

Ver también: https://github.com/electrolinux/phpquery

Zend_Dom

Zend_Dom proporciona herramientas para trabajar con estructuras y documentos DOM. Actualmente, ofrecemos Zend_Dom_Query, que proporciona una interfaz unificada para consultar documentos DOM utilizando selectores XPath y CSS.

QueryPath

QueryPath es una biblioteca PHP para manipular XML y HTML. Está diseñado para funcionar no solo con archivos locales, sino también con servicios web y recursos de bases de datos. Implementa gran parte de la interfaz jQuery (incluidos los selectores de estilo CSS), pero está muy optimizado para el uso del lado del servidor. Se puede instalar a través de Composer.

fDOMDocument

fDOMDocument extiende el DOM estándar para usar excepciones en todas las ocasiones de errores en lugar de advertencias o avisos de PHP. También agregan varios métodos personalizados y accesos directos para mayor comodidad y para simplificar el uso de DOM.

saber / xml

saber / xml es una biblioteca que envuelve y amplía las clases XMLReader y XMLWriter para crear un sistema de mapeo y patrón de diseño simple "xml a objeto / matriz". La escritura y lectura de XML es de un solo paso y, por lo tanto, puede ser rápida y requiere poca memoria en archivos XML grandes.

FluidXML

FluidXML es una biblioteca PHP para manipular XML con una API concisa y fluida. Aprovecha XPath y el patrón de programación fluido para ser divertido y efectivo.


De terceros (no basado en libxml)

El beneficio de construir sobre DOM / libxml es que obtiene un buen rendimiento de inmediato porque se basa en una extensión nativa. Sin embargo, no todas las bibliotecas de terceros siguen esta ruta. Algunos de ellos se enumeran a continuación

Analizador de DOM HTML simple PHP

  • ¡Un analizador HTML DOM escrito en PHP5 + le permite manipular HTML de una manera muy fácil!
  • Requiere PHP 5+.
  • Admite HTML no válido.
  • Busque etiquetas en una página HTML con selectores como jQuery.
  • Extrae contenido de HTML en una sola línea.

Generalmente no recomiendo este analizador. El código base es horrible y el analizador en sí es bastante lento y tiene mucha memoria. No todos los selectores de jQuery (como selectores de niños) es posible. Cualquiera de las bibliotecas basadas en libxml debería superar esto fácilmente.

Analizador PHP Html

PHPHtmlParser es un analizador html simple y flexible que le permite seleccionar etiquetas usando cualquier selector css, como jQuery. El objetivo es ayudar en el desarrollo de herramientas que requieren una forma rápida y fácil de raspar html, ¡sea válido o no! Este proyecto fue apoyado originalmente por sunra / php-simple-html-dom-parser, pero el soporte parece haberse detenido, por lo que este proyecto es mi adaptación de su trabajo anterior.

Nuevamente, no recomendaría este analizador. Es bastante lento con un uso elevado de la CPU. Tampoco hay una función para borrar la memoria de los objetos DOM creados. Estos problemas aumentan particularmente con los bucles anidados. La documentación en sí es inexacta y está mal escrita, sin respuestas a las correcciones desde el 14 de abril del 16.

Ganon

  • Un tokenizador universal y un analizador DOM HTML / XML / RSS
  •    Ability to manipulate elements and their attributes
    
  •    Supports invalid HTML and UTF8
    
  •    Can perform advanced CSS3-like queries on elements (like jQuery -- namespaces supported) 
    
  • Un embellecedor HTML (como HTML Tidy)
  •    Minify CSS and Javascript
    
  •    Sort attributes, change character case, correct indentation, etc. 
    
  • extensible
  •    Parsing documents using callbacks based on current character/token
    
  •    Operations separated in smaller functions for easy overriding 
    
  • Rapido y facil

Nunca lo usé. No puedo decir si es bueno.


HTML 5

Puede utilizar lo anterior para analizar HTML5, pero puede haber peculiaridades debido al marcado que permite HTML5. Entonces, para HTML5, debe considerar el uso de un analizador dedicado, como

html5lib

Implementaciones de Python y PHP de un analizador HTML basado en la especificación WHATWG HTML5 para una máxima compatibilidad con los principales navegadores web de escritorio.

Es posible que veamos analizadores más dedicados una vez que HTML5 esté finalizado. También hay una entrada de blog de W3 titulada Procedimientos para el análisis sintáctico de html 5 vale la pena echarle un vistazo.


Servicios web

Si no tiene ganas de programar PHP, también puede utilizar los servicios web. En general, encontré muy poca utilidad para estos, pero solo somos yo y mis casos de uso.

ScraperWiki.

La interfaz externa de ScraperWiki le permite extraer datos en la forma que desee para usar en la web o en sus propias aplicaciones. También puede extraer información sobre el estado de cualquier raspador.


Expresiones regulares

Último y menos recomendado, puede extraer datos de HTML con expresiones regulares. En general, se desaconseja el uso de expresiones regulares en HTML.

La mayoría de los fragmentos que encontrará en la web para coincidir con el marcado son frágiles. En la mayoría de los casos, solo funcionan para una parte muy particular de HTML. Pequeños cambios de marcado, como agregar espacios en blanco en algún lugar, o agregar o cambiar atributos en una etiqueta, pueden hacer que la expresión regular falle cuando no está escrita correctamente. Debe saber lo que está haciendo antes de utilizar RegEx en HTML.

Los analizadores de HTML ya conocen las reglas sintácticas de HTML. Las expresiones regulares deben enseñarse para cada nueva expresión regular que escriba. Las expresiones regulares están bien en algunos casos, pero realmente depende de su caso de uso.

Usted puede escribir analizadores más confiables, pero escribiendo un completo y confiable El analizador personalizado con expresiones regulares es una pérdida de tiempo cuando las bibliotecas antes mencionadas ya existen y hacen un trabajo mucho mejor en esto.

Ver también Análisis de HTML a la manera de Cthulhu


Libros

Si quieres gastar algo de dinero, echa un vistazo a

No estoy afiliado a PHP Architect ni a los autores.

Respondido 04 Feb 21, 20:02

@Naveed eso depende de tus necesidades. No necesito consultas de CSS Selector, por lo que uso DOM con XPath exclusivamente. phpQuery pretende ser un puerto jQuery. Zend_Dom es liviano. Realmente tienes que revisarlos para ver cuál te gusta más. - Gordon

@ Ms2ger Principalmente, pero no del todo. Como ya se señaló anteriormente, puede usar los analizadores basados ​​en libxml, pero hay casos especiales en los que se ahogan. Si necesita la máxima compatibilidad, es mejor que utilice un analizador dedicado. Prefiero mantener la distinción. - Gordon

Su punto para no usar PHP Simple HTML DOM Parser parece discutible. - Petaj

A partir del 29 de marzo de 2012, DOM no es compatible con html5, XMLReader no es compatible con HTML y la última confirmación en html5lib para PHP es en septiembre de 2009. ¿Qué usar para analizar HTML5, HTML4 y XHTML? - Shiplu Mokaddim

@Nasha Excluí deliberadamente la infame perorata de Zalgo de la lista anterior porque no es demasiado útil por sí sola y conduce a un gran culto al cargo desde que fue escrito. La gente fue abofeteada con ese enlace sin importar cuán apropiada hubiera sido una expresión regular como solución. Para obtener una opinión más equilibrada, consulte el enlace I sí logró incluir en su lugar y revisar los comentarios en stackoverflow.com/questions/4245008/… - Gordon

Trata Analizador DOM HTML simple

  • ¡Un analizador HTML DOM escrito en PHP 5+ que le permite manipular HTML de una manera muy fácil!
  • Requiere PHP 5+.
  • Admite HTML no válido.
  • Busque etiquetas en una página HTML con selectores como jQuery.
  • Extrae contenido de HTML en una sola línea.
  • Descargar


Ejemplos:

Cómo obtener elementos HTML:

// Create DOM from URL or file
$html = file_get_html('http://www.example.com/');

// Find all images
foreach($html->find('img') as $element)
       echo $element->src . '<br>';

// Find all links
foreach($html->find('a') as $element)
       echo $element->href . '<br>';


Cómo modificar elementos HTML:

// Create DOM from string
$html = str_get_html('<div id="hello">Hello</div><div id="world">World</div>');

$html->find('div', 1)->class = 'bar';

$html->find('div[id=hello]', 0)->innertext = 'foo';

echo $html;


Extraer contenido de HTML:

// Dump contents (without tags) from HTML
echo file_get_html('http://www.google.com/')->plaintext;


Raspado de Slashdot:

// Create DOM from URL
$html = file_get_html('http://slashdot.org/');

// Find all article blocks
foreach($html->find('div.article') as $article) {
    $item['title']     = $article->find('div.title', 0)->plaintext;
    $item['intro']    = $article->find('div.intro', 0)->plaintext;
    $item['details'] = $article->find('div.details', 0)->plaintext;
    $articles[] = $item;
}

print_r($articles);

Respondido 28 Oct 15, 20:10

Bueno, en primer lugar, hay cosas para las que debo prepararme, como el mal DOM, el código Invlid, también el análisis de js contra el motor DNSBL, esto también se usará para buscar sitios / contenido malicioso, también como he construido mi sitio en torno a un marco i Lo hemos construido debe ser limpio, legible y bien estructurado. SimpleDim es genial, pero el código es un poco desordenado. RobertPitt

@Robert, es posible que también desee consultar htmlpurifier.org por las cosas relacionadas con la seguridad. - Gordon

Tiene un punto válido: simpleHTMLDOM es difícil de extender, a menos que use un patrón de decorador, que encuentro difícil de manejar. Me he encontrado estremecimiento simplemente haciendo cambios en las clases subyacentes. - Erik

Lo que hice fue ejecutar mi html a través de tidy antes de enviarlo a SimpleDOM. - MB34

Estoy usando esto actualmente, ejecutándolo como parte de un proyecto para procesar algunos cientos de URL. Se está volviendo muy lento y persisten los tiempos de espera regulares. Es un excelente guión para principiantes e intuitivamente fácil de aprender, pero demasiado básico para proyectos más avanzados. - luke_mclachlan

Sólo tiene que utilizar DOMDocument-> loadHTML () y terminar con eso. El algoritmo de análisis de HTML de libxml es bastante bueno y rápido y, contrariamente a la creencia popular, no se ahoga con HTML mal formado.

respondido 26 nov., 08:23

Cierto. Y funciona con las clases XPath y XSLTProcessor integradas de PHP, que son excelentes para extraer contenido. - Kornel

Para HTML realmente alterado, siempre puede ejecutarlo a través de htmltidy antes de entregarlo a DOM. Siempre que necesito extraer datos de HTML, siempre uso DOM, o al menos simplexml. - Frank Farmer

Otra cosa con la carga de HTML i con formato incorrecto es que sería aconsejable llamar a libxml_use_internal_errors (true) para evitar advertencias que dejarán de analizar. - Husky

He usado DOMDocument para analizar alrededor de 1000 fuentes html (en varios idiomas codificados con diferentes conjuntos de caracteres) sin ningún problema. Es posible que tenga problemas de codificación con esto, pero no son insuperables. Necesita saber 3 cosas: 1) loadHTML usa el conjunto de caracteres de la metaetiqueta para determinar la codificación 2) # 2 puede conducir a una detección de codificación incorrecta si el contenido html no incluye esta información 3) los caracteres UTF-8 incorrectos pueden disparar el analizador. En tales casos, use una combinación de mb_detect_encoding () y la codificación / conversión / eliminación del código de caracteres UTF-8 incorrectos del analizador RSS Simplepie para soluciones alternativas. - Cero

DOM en realidad es compatible con XPath, eche un vistazo a DOMXPath. - Ryan McCue

Por qué no deberías y cuando deberías usar expresiones regulares?

En primer lugar, un nombre inapropiado común: las expresiones regulares no son para "Analizando" HTML. Sin embargo, las expresiones regulares pueden "extraerlos" datos. Extraer es para lo que están hechos. El principal inconveniente de la extracción de expresiones regulares HTML sobre los conjuntos de herramientas SGML adecuados o los analizadores XML de línea de base es su esfuerzo sintáctico y su fiabilidad variable.

Considere que hacer una expresión regular de extracción de HTML algo confiable:

<a\s+class="?playbutton\d?[^>]+id="(\d+)".+?    <a\s+class="[\w\s]*title
[\w\s]*"[^>]+href="(http://[^">]+)"[^>]*>([^<>]+)</a>.+?

es mucho menos legible que un simple phpQuery o QueryPath equivalente:

$div->find(".stationcool a")->attr("title");

Sin embargo, existen casos de uso específicos en los que pueden ayudar.

  • Muchas interfaces de recorrido de DOM no revelan comentarios HTML <!--, que sin embargo son a veces los anclajes más útiles para la extracción. En particular, variaciones de pseudo-HTML <$var> o los residuos de SGML son fáciles de domesticar con expresiones regulares.
  • A menudo, las expresiones regulares pueden ahorrar posprocesamiento. Sin embargo, las entidades HTML a menudo requieren cuidados manuales.
  • Y por último, para eTareas extremadamente simples como extraer

A veces incluso es aconsejable extraer previamente un fragmento de HTML utilizando expresiones regulares /<!--CONTENT-->(.+?)<!--END-->/ y procese el resto utilizando las interfaces del analizador HTML más simples.

Nota: De hecho tengo esto applicación, donde empleo el análisis XML y las expresiones regulares de forma alternativa. Apenas la semana pasada, el análisis de PyQuery se rompió y la expresión regular aún funcionaba. Sí, raro, y yo mismo no puedo explicarlo. Pero así sucedió.
Así que por favor no desestime las consideraciones del mundo real, solo porque no coincide con el meme regex = evil. Pero tampoco votemos demasiado por esto. Es solo una nota al margen de este tema.

contestado el 07 de mayo de 16 a las 13:05

DOMComment puede leer comentarios, por lo que no hay razón para usar Regex para eso. - Gordon

Ni los kits de herramientas SGML ni los analizadores XML son adecuados para analizar HTML del mundo real. Para eso, solo es apropiado un analizador HTML dedicado. - Alohci

@Alohci DOM usos libxml y libxml tiene un analizador HTML separado módulo que se utilizará al cargar HTML con loadHTML() por lo que puede cargar mucho HTML del "mundo real" (leído roto). - Gordon

Bueno, solo un comentario sobre su punto de vista de la "consideración del mundo real". Claro, hay situaciones útiles para Regex al analizar HTML. Y también hay situaciones útiles para usar GOTO. Y hay situaciones útiles para variables-variables. Por lo tanto, ninguna implementación en particular es definitivamente code-rot para usarlo. Pero es una señal de advertencia MUY fuerte. Y es probable que el desarrollador promedio no tenga los suficientes matices para notar la diferencia. Entonces, como regla general, Regex GOTO y Variable-Variables son todos malvados. Hay usos no malignos, pero esas son las excepciones (y raras en eso) ... (en mi humilde opinión) - ircmaxell

@mario: En realidad, HTML enlatado ser analizado "correctamente" usando expresiones regulares, aunque normalmente se necesitan varias para hacer un buen trabajo. Es solo un dolor real en el caso general. En casos específicos con entradas bien definidas, roza lo trivial. Esos son los casos que la gente debemos estar usando expresiones regulares. Los grandes analizadores pesados ​​y hambrientos son realmente lo que necesita para casos generales, aunque no siempre está claro para el usuario casual dónde trazar esa línea. El código que sea más simple y fácil, gana. - tchrist

phpQuery y QueryPath son extremadamente similares a la hora de replicar la fluida API de jQuery. Por eso también son dos de los enfoques más fáciles para correctamente analizar HTML en PHP.

Ejemplos de QueryPath

Básicamente, primero crea un árbol DOM consultable a partir de una cadena HTML:

 $qp = qp("<html><body><h1>title</h1>..."); // or give filename or URL

El objeto resultante contiene una representación de árbol completa del documento HTML. Se puede atravesar utilizando métodos DOM. Pero el enfoque común es usar selectores CSS como en jQuery:

 $qp->find("div.classname")->children()->...;

 foreach ($qp->find("p img") as $img) {
     print qp($img)->attr("src");
 }

En su mayoría, desea usar simple #id y .class or DIV selectores de etiquetas para ->find(). Pero también puedes usar XPath declaraciones, que a veces son más rápidas. También métodos típicos de jQuery como ->children() y ->text() y particularmente ->attr() simplifique la extracción de los fragmentos de HTML correctos. (Y ya tienen sus entidades SGML decodificadas).

 $qp->xpath("//div/p[1]");  // get first paragraph in a div

QueryPath también permite inyectar nuevas etiquetas en la secuencia (->append), y luego generar y embellecer un documento actualizado (->writeHTML). No solo puede analizar HTML con formato incorrecto, sino también varios dialectos XML (con espacios de nombres) e incluso extraer datos de microformatos HTML (XFN, vCard).

 $qp->find("a[target=_blank]")->toggleClass("usability-blunder");

.

phpQuery o QueryPath?

Generalmente, QueryPath es más adecuado para la manipulación de documentos. Si bien phpQuery también implementa algunos métodos pseudo AJAX (solo solicitudes HTTP) para parecerse más a jQuery. Se dice que phpQuery suele ser más rápido que QueryPath (debido a que tiene menos funciones generales).

Para obtener más información sobre las diferencias, consulte esta comparación en la máquina wayback de tagbyte.org. (La fuente original desapareció, así que aquí hay un enlace de archivo de Internet. Sí, aún puede localizar las páginas que faltan, personas)

Y aqui una introducción completa de QueryPath.

Ventajas

  • Sencillez y confiabilidad
  • Alternativas fáciles de usar ->find("a img, a object, div a")
  • Eliminación de escape de datos adecuada (en comparación con grepping de expresiones regulares)

respondido 23 nov., 12:08

Simple HTML DOM es un gran analizador de código abierto:

simplehtmldom.sourceforge

Trata los elementos DOM de una manera orientada a objetos, y la nueva iteración tiene mucha cobertura para el código no compatible. También hay algunas funciones geniales como las que vería en JavaScript, como la función "buscar", que devolverá todas las instancias de elementos de ese nombre de etiqueta.

He usado esto en varias herramientas, probándolo en muchos tipos diferentes de páginas web, y creo que funciona muy bien.

Respondido 28 Oct 15, 20:10

Un enfoque general que no he visto mencionado aquí es ejecutar HTML a través Ordenado, que se puede configurar para escupir XHTML válido garantizado. Entonces puede usar cualquier biblioteca XML antigua en él.

Pero para su problema específico, debería echar un vistazo a este proyecto: http://fivefilters.org/content-only/ - es una versión modificada del legibilidad algoritmo, que está diseñado para extraer solo el contenido textual (no encabezados ni pies de página) de una página.

contestado el 01 de mayo de 11 a las 06:05

Para 1a y 2: votaría por la nueva clase de componente Symfony DOMCrawler ( DomCrawler ). Esta clase permite consultas similares a los selectores CSS. Eche un vistazo a esta presentación para ver ejemplos del mundo real: noticias-del-mundo-symfony2.

El componente está diseñado para funcionar de forma independiente y se puede utilizar sin Symfony.

El único inconveniente es que solo funcionará con PHP 5.3 o posterior.

Respondido el 14 de junio de 13 a las 14:06

Las consultas CSS de tipo jquery están bien dichas, porque hay algunas cosas que faltan en la documentación de w3c, pero están presentes como características adicionales en jquery. - Nikola Petkanski

Esto se conoce comúnmente como raspado de pantalla, por cierto. La biblioteca que he usado para esto es Analizador simple de HTML Dom.

Respondido 26 ago 10, 21:08

No es estrictamente cierto (en.wikipedia.org/wiki/Screen_scraping#Screen_scraping). La pista está en "pantalla"; en el caso descrito, no hay ninguna pantalla involucrada. Aunque, es cierto, el término ha sufrido una gran cantidad de mal uso reciente. - Bobby Jack

No estoy raspando la pantalla, el contenido que se analizará será autorizado por el proveedor de contenido según mi acuerdo. - RobertPitt

Hemos creado bastantes rastreadores para nuestras necesidades antes. Al final del día, generalmente son las expresiones regulares simples las que hacen lo mejor. Si bien las bibliotecas enumeradas anteriormente son buenas por la razón por la que se crean, si sabe lo que está buscando, las expresiones regulares son una forma más segura de hacerlo, ya que puede manejar también no válidas HTML/XHTML estructuras, que fallarían si se cargaran a través de la mayoría de los analizadores.

Respondido 01 Abr '14, 02:04

Recomiendo Analizador de DOM HTML simple PHP.

Realmente tiene buenas características, como:

foreach($html->find('img') as $element)
       echo $element->src . '<br>';

Respondido 28 Oct 15, 20:10

Esto suena como una buena descripción de la tarea del W3C. XPath tecnología. Es fácil expresar consultas como "devolver todo href atributos en img etiquetas que están anidadas en <foo><bar><baz> elements. "Como no soy un aficionado a PHP, no puedo decirle en qué forma XPath puede estar disponible. Si puede llamar a un programa externo para procesar el archivo HTML, debería poder usar una versión de línea de comandos de XPath. intro, ver http://en.wikipedia.org/wiki/XPath.

Respondido 14 Abr '11, 23:04

Alternativas de terceros a SimpleHtmlDom que usan DOM en lugar de String Parsing: phpQuery, Zend_Dom, QueryPath y FluentDom.

Respondido el 26 de diciembre de 13 a las 22:12

Si ya copia mis comentarios, al menos vincúlelos correctamente;) Eso debería ser: Alternativas de terceros sugeridas para SimpleHtmlDom que realmente usan DOM en lugar de analizar cadenas: phpQuery, Zend_Dom, QueryPath y FluentDom. - Gordon

Las buenas respuestas son una gran fuente. stackoverflow.com/questions/3606792/… - johnlemon

Sí, puede usar simple_html_dom para este propósito. Sin embargo, he trabajado bastante con simple_html_dom, particularmente para web scraping y lo he encontrado demasiado vulnerable. Hace el trabajo básico, pero no lo recomendaré de todos modos.

Nunca he usado curl para este propósito, pero lo que he aprendido es que curl puede hacer el trabajo de manera mucho más eficiente y es mucho más sólido.

Por favor, consulte este enlace:raspado-sitios-web-con-curl

Respondido 12 Feb 21, 13:02

rizo puede obtener el archivo, pero no analizará HTML por usted. Esa es la parte difícil. - cHao

QueryPath es bueno, pero tenga cuidado con el "estado de seguimiento" porque si no se dio cuenta de lo que significa, puede significar que pierde mucho tiempo de depuración tratando de averiguar qué sucedió y por qué el código no funciona.

Lo que significa es que cada llamada en el conjunto de resultados modifica el conjunto de resultados en el objeto, no es encadenable como en jquery donde cada enlace es un conjunto nuevo, tiene un conjunto único que es el resultado de su consulta y cada llamada de función modifica ese único conjunto.

Para obtener un comportamiento similar a jquery, debe bifurcarse antes de realizar una operación de filtro / modificación, lo que significa que reflejará lo que sucede en jquery mucho más de cerca.

$results = qp("div p");
$forename = $results->find("input[name='forename']");

$results ahora contiene el conjunto de resultados para input[name='forename'] NO la consulta original "div p" esto me hizo tropezar mucho, lo que encontré fue que QueryPath rastrea los filtros y encuentra y todo lo que modifica sus resultados y los almacena en el objeto. necesitas hacer esto en su lugar

$forename = $results->branch()->find("input[name='forname']")

luego $results no se modificará y puede reutilizar el conjunto de resultados una y otra vez, tal vez alguien con mucho más conocimiento pueda aclarar esto un poco, pero es básicamente así por lo que he encontrado.

Respondido el 31 de enero de 15 a las 13:01

Dominio HTML avanzado es un HTML simple DOM reemplazo que ofrece la misma interfaz, pero está basado en DOM, lo que significa que no ocurre ninguno de los problemas de memoria asociados.

También tiene compatibilidad completa con CSS, que incluye jQuery extensiones.

Respondido el 28 de diciembre de 15 a las 19:12

Obtuve buenos resultados de Advanced Html Dom, y creo que debería estar en la lista de la respuesta aceptada. Sin embargo, una cosa importante que debe saber para cualquiera que confíe en su "El objetivo de este proyecto es ser un reemplazo directo basado en DOM para la simple biblioteca html dom de PHP ... Si usa file / str_get_html, entonces no necesita Cambia cualquier cosa." archive.is/QtSuj#selection-933.34-933.100 es que es posible que deba realizar cambios en su código para adaptarse a algunas incompatibilidades. He notado cuatro que conozco en los problemas de github del proyecto. github.com/monkeysuffrage/advanced_html_dom/issues - ChrisJJ

Trabajó ! Gracias - Faisal Shani

Para obtener HTML5, html5 lib se ha abandonado durante años. La única biblioteca HTML5 que puedo encontrar con una actualización reciente y registros de mantenimiento es html5-php que se llevó a la versión beta 1.0 hace poco más de una semana.

Respondido 28 Oct 15, 20:10

Creé una biblioteca llamada PHPPowertools / DOM-Query, que le permite rastrear documentos HTML5 y XML como lo hace con jQuery.

Debajo del capó, usa Symfony / DomCrawler para la conversión de selectores CSS a XPath selectores. Siempre usa el mismo DomDocument, incluso cuando pasa un objeto a otro, para garantizar un rendimiento decente.


Ejemplo de uso:

namespace PowerTools;

// Get file content
$htmlcode = file_get_contents('https://github.com');

// Define your DOMCrawler based on file string
$H = new DOM_Query($htmlcode);

// Define your DOMCrawler based on an existing DOM_Query instance
$H = new DOM_Query($H->select('body'));

// Passing a string (CSS selector)
$s = $H->select('div.foo');

// Passing an element object (DOM Element)
$s = $H->select($documentBody);

// Passing a DOM Query object
$s = $H->select( $H->select('p + p'));

// Select the body tag
$body = $H->select('body');

// Combine different classes as one selector to get all site blocks
$siteblocks = $body->select('.site-header, .masthead, .site-body, .site-footer');

// Nest your methods just like you would with jQuery
$siteblocks->select('button')->add('span')->addClass('icon icon-printer');

// Use a lambda function to set the text of all site blocks
$siteblocks->text(function( $i, $val) {
    return $i . " - " . $val->attr('class');
});

// Append the following HTML to all site blocks
$siteblocks->append('<div class="site-center"></div>');

// Use a descendant selector to select the site's footer
$sitefooter = $body->select('.site-footer > .site-center');

// Set some attributes for the site's footer
$sitefooter->attr(array('id' => 'aweeesome', 'data-val' => 'see'));

// Use a lambda function to set the attributes of all site blocks
$siteblocks->attr('data-val', function( $i, $val) {
    return $i . " - " . $val->attr('class') . " - photo by Kelly Clark";
});

// Select the parent of the site's footer
$sitefooterparent = $sitefooter->parent();

// Remove the class of all i-tags within the site's footer's parent
$sitefooterparent->select('i')->removeAttr('class');

// Wrap the site's footer within two nex selectors
$sitefooter->wrap('<section><div class="footer-wrapper"></div></section>');

[...]

Métodos admitidos:


  1. Renombrado 'seleccionar', por razones obvias
  2. Renombrado 'void', ya que 'vacío' es una palabra reservada en PHP

NOTA:

La biblioteca también incluye su propio autocargador de configuración cero para bibliotecas compatibles con PSR-0. El ejemplo incluido debería funcionar de inmediato sin ninguna configuración adicional. Alternativamente, puede usarlo con composer.

Respondido el 20 de junio de 20 a las 12:06

Parece la herramienta adecuada para el trabajo, pero no se carga para mí en PHP 5.6.23 en Worpress. ¿Alguna instrucción adicional sobre cómo incluirlo correctamente? Incluido con: define ("BASE_PATH", dirname (ARCHIVO)); define ("BIBLIOTECA_PATH", BASE_PATH. DIRECTORY_SEPARATOR. 'lib / vendor'); requieren LIBRARY_PATH. DIRECTORY_SEPARATOR. 'Loader.php'; Loader :: init (array (LIBRARY_PATH, USER_PATH)); en functions.php - laboratorio de litio

He escrito un analizador XML de propósito general que puede manejar fácilmente archivos GB. Está basado en XMLReader y es muy fácil de usar:

$source = new XmlExtractor("path/to/tag", "/path/to/file.xml");
foreach ($source as $tag) {
    echo $tag->field1;
    echo $tag->field2->subfield1;
}

Aquí está el repositorio de github: XmlExtractor

contestado el 12 de mayo de 13 a las 05:05

Otra opción que puedes probar es QueryPath. Está inspirado en jQuery, pero en el servidor en PHP y se usa en Drupal.

Respondido 28 Oct 18, 17:10

Podrías intentar usar algo como HTML Tidy para limpiar cualquier HTML "roto" y convertir el HTML a XHTML, que luego puede analizar con un analizador XML.

respondido 16 nov., 08:01

XML_HTMLSax es bastante estable, incluso si ya no se mantiene. Otra opción podría ser canalizar su HTML a través de HTML ordenado y luego analizarlo con herramientas XML estándar.

respondido 15 nov., 08:22

Hay muchas formas de procesar DOM HTML / XML, de las cuales la mayoría ya se han mencionado. Por lo tanto, no intentaré enumerarlos yo mismo.

Simplemente quiero agregar que personalmente prefiero usar la extensión DOM y por qué:

  • Hace un uso óptimo de la ventaja de rendimiento del código C subyacente.
  • es OO PHP (y me permite subclasificarlo)
  • es un nivel bastante bajo (lo que me permite usarlo como una base no hinchada para un comportamiento más avanzado)
  • proporciona acceso a todas las partes del DOM (a diferencia de, por ejemplo, SimpleXml, que ignora algunas de las características XML menos conocidas)
  • tiene una sintaxis utilizada para el rastreo de DOM que es similar a la sintaxis utilizada en Javascript nativo.

Y aunque echo de menos la posibilidad de utilizar selectores CSS para DOMDocument, hay una forma bastante simple y conveniente de agregar esta característica: subclasificar el DOMDocument y agregando JS-like querySelectorAll y querySelector métodos a su subclase.

Para analizar los selectores, recomiendo usar el muy minimalista Componente CssSelector from the Marco Symfony. Este componente simplemente traduce los selectores CSS a selectores XPath, que luego se pueden alimentar a un DOMXpath para recuperar la lista de nodos correspondiente.

Luego puede usar esta subclase (todavía de muy bajo nivel) como base para clases de más alto nivel, destinadas, por ejemplo, a analizar tipos muy específicos de XML o agregar un comportamiento más similar a jQuery.

El siguiente código viene directamente de mi Biblioteca DOM-Query y usa la técnica que describí.

Para el análisis de HTML:

namespace PowerTools;

use \Symfony\Component\CssSelector\CssSelector as CssSelector;

class DOM_Document extends \DOMDocument {
    public function __construct($data = false, $doctype = 'html', $encoding = 'UTF-8', $version = '1.0') {
        parent::__construct($version, $encoding);
        if ($doctype && $doctype === 'html') {
            @$this->loadHTML($data);
        } else {
            @$this->loadXML($data);
        }
    }

    public function querySelectorAll($selector, $contextnode = null) {
        if (isset($this->doctype->name) && $this->doctype->name == 'html') {
            CssSelector::enableHtmlExtension();
        } else {
            CssSelector::disableHtmlExtension();
        }
        $xpath = new \DOMXpath($this);
        return $xpath->query(CssSelector::toXPath($selector, 'descendant::'), $contextnode);
    }

    [...]

    public function loadHTMLFile($filename, $options = 0) {
        $this->loadHTML(file_get_contents($filename), $options);
    }

    public function loadHTML($source, $options = 0) {
        if ($source && $source != '') {
            $data = trim($source);
            $html5 = new HTML5(array('targetDocument' => $this, 'disableHtmlNsInDom' => true));
            $data_start = mb_substr($data, 0, 10);
            if (strpos($data_start, '<!DOCTYPE ') === 0 || strpos($data_start, '<html>') === 0) {
                $html5->loadHTML($data);
            } else {
                @$this->loadHTML('<!DOCTYPE html><html><head><meta charset="' . $encoding . '" /></head><body></body></html>');
                $t = $html5->loadHTMLFragment($data);
                $docbody = $this->getElementsByTagName('body')->item(0);
                while ($t->hasChildNodes()) {
                    $docbody->appendChild($t->firstChild);
                }
            }
        }
    }

    [...]
}

Véase también Analizar documentos XML con selectores CSS por el creador de Symfony, Fabien Potencier, sobre su decisión de crear el componente CssSelector para Symfony y cómo usarlo.

Respondido el 15 de enero de 16 a las 19:01

La Symfony framework tiene paquetes que pueden analizar el HTML, y puede usar el estilo CSS para seleccionar el DOM En lugar de usar XPath.

Respondido 01 Abr '14, 02:04

Con FluidXML puede consultar e iterar XML usando XPath y Selectores CSS.

$doc = fluidxml('<html>...</html>');

$title = $doc->query('//head/title')[0]->nodeValue;

$doc->query('//body/p', 'div.active', '#bgId')
        ->each(function($i, $node) {
            // $node is a DOMNode.
            $tag   = $node->nodeName;
            $text  = $node->nodeValue;
            $class = $node->getAttribute('class');
        });

https://github.com/servo-php/fluidxml

respondido 07 mar '16, 19:03

JSON y matriz de XML en tres líneas:

$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);

¡Sí!

Respondido 28 Oct 15, 20:10

Hay varias razones para no analizar HTML mediante expresiones regulares. Pero, si tiene el control total de lo que se generará HTML, puede hacerlo con una simple expresión regular.

Arriba hay una función que analiza HTML mediante una expresión regular. Tenga en cuenta que esta función es muy sensible y exige que el HTML obedezca ciertas reglas, pero funciona muy bien en muchos escenarios. Si desea un analizador simple y no desea instalar bibliotecas, pruebe esto:

function array_combine_($keys, $values) {
    $result = array();
    foreach ($keys as $i => $k) {
        $result[$k][] = $values[$i];
    }
    array_walk($result, create_function('&$v', '$v = (count($v) == 1)? array_pop($v): $v;'));

    return $result;
}

function extract_data($str) {
    return (is_array($str))
        ? array_map('extract_data', $str)
        : ((!preg_match_all('#<([A-Za-z0-9_]*)[^>]*>(.*?)</\1>#s', $str, $matches))
            ? $str
            : array_map(('extract_data'), array_combine_($matches[1], $matches[2])));
}

print_r(extract_data(file_get_contents("http://www.google.com/")));

Respondido 28 Oct 15, 20:10

He creado una biblioteca llamada HTML5DOMDocument que está disponible gratuitamente en https://github.com/ivopetkov/html5-dom-document-php

También admite selectores de consultas que creo que serán de gran ayuda en su caso. Aquí hay un código de ejemplo:

$dom = new IvoPetkov\HTML5DOMDocument();
$dom->loadHTML('<!DOCTYPE html><html><body><h1>Hello</h1><div class="content">This is some text</div></body></html>');
echo $dom->querySelector('h1')->innerHTML;

Respondido el 21 de diciembre de 17 a las 11:12

Si está familiarizado con el selector de jQuery, puede usar ScarletsQuery para PHP

<pre><?php
include "ScarletsQuery.php";

// Load the HTML content and parse it
$html = file_get_contents('https://www.lipsum.com');
$dom = Scarlets\Library\MarkupLanguage::parseText($html);

// Select meta tag on the HTML header
$description = $dom->selector('head meta[name="description"]')[0];

// Get 'content' attribute value from meta tag
print_r($description->attr('content'));

$description = $dom->selector('#Content p');

// Get element array
print_r($description->view);

Esta biblioteca suele tardar menos de 1 segundo en procesar html sin conexión.
También acepta HTML no válido o comillas faltantes en atributos de etiquetas.

Respondido 16 ago 18, 15:08

El mejor método para analizar XML:

$xml='http://www.example.com/rss.xml';
$rss = simplexml_load_string($xml);
$i = 0;
foreach ($rss->channel->item as $feedItem) {
  $i++;
  echo $title=$feedItem->title;
  echo '<br>';
  echo $link=$feedItem->link;
  echo '<br>';
  if($feedItem->description !='') {
    $des=$feedItem->description;
  } else {
    $des='';
  }
  echo $des;
  echo '<br>';
  if($i>5) break;
}

Respondido el 23 de enero de 20 a las 11:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.