¿Cuáles son las ventajas y desventajas de los principales analizadores HTML de Java? [cerrado]
Al buscar en SO y Google, descubrí que hay algunos analizadores HTML de Java que son recomendados constantemente por varias partes. Desafortunadamente, es difícil encontrar información sobre las fortalezas y debilidades de las distintas bibliotecas. Espero que algunas personas hayan dedicado algo de tiempo a comparar estas bibliotecas y puedan compartir lo que han aprendido.
Esto es lo que he visto:
- JTidy
- NekoHTML
- jsopa
- EtiquetaSopa
Y si hay un analizador importante que me he perdido, también me encantaría conocer sus ventajas y desventajas.
¡Gracias!
General
Casi todos los analizadores HTML conocidos implementan la API DOM W3C (parte de la API JAXP, API Java para procesamiento XML) y le brindan un org.w3c.dom.Document
respaldo que está listo para uso directo por la API JAXP. Las principales diferencias suelen encontrarse en las características del analizador en cuestión. La mayoría de los analizadores son hasta cierto punto indulgentes con HTML no bien formado ("tagsoup"), como JTidy , NekoHTML , TagSoup y HtmlCleaner . Por lo general, se utilizan este tipo de analizadores de HTML para "ordenar" la fuente HTML (por ejemplo, reemplazando el HTML válido <br>
por un XML válido <br />
), de modo que pueda recorrerlo "de la manera habitual" utilizando W3C DOM y JAXP API.
Los únicos que destacan son HtmlUnit y Jsoup .
Unidad HTML
HtmlUnit proporciona una API completamente propia que le brinda la posibilidad de actuar como un navegador web mediante programación. Es decir, ingresar valores de formulario, hacer clic en elementos, invocar JavaScript, etcétera. Es mucho más que un simple analizador HTML. Es un verdadero "navegador web sin GUI" y una herramienta de prueba de unidades HTML.
sopa
Jsoup también proporciona una API completamente propia. Le brinda la posibilidad de seleccionar elementos usando selectores CSS tipo jQuery y proporciona una API ingeniosa para recorrer el árbol HTML DOM para obtener los elementos de interés.
En particular, atravesar el árbol HTML DOM es la principal fortaleza de Jsoup. Aquellos que han trabajado con ellos org.w3c.dom.Document
saben lo doloroso que es atravesar el DOM utilizando las API NodeList
y detalladas Node
. Es cierto que XPath
hace la vida más fácil, pero aún así, es otra curva de aprendizaje y puede terminar siendo aún detallada.
Aquí hay un ejemplo que utiliza un analizador DOM W3C "simple" como JTidy en combinación con XPath para extraer el primer párrafo de su pregunta y los nombres de todos los que respondieron (estoy usando XPath ya que sin él, el código necesario para recopilar la información de interés de lo contrario crecería 10 veces más, sin escribir métodos de utilidad/ayuda).
String url = "http://stackoverflow.com/questions/3152138";
Document document = new Tidy().parseDOM(new URL(url).openStream(), null);
XPath xpath = XPathFactory.newInstance().newXPath();
Node question = (Node) xpath.compile("//*[@id='question']//*[contains(@class,'post-text')]//p[1]").evaluate(document, XPathConstants.NODE);
System.out.println("Question: " + question.getFirstChild().getNodeValue());
NodeList answerers = (NodeList) xpath.compile("//*[@id='answers']//*[contains(@class,'user-details')]//a[1]").evaluate(document, XPathConstants.NODESET);
for (int i = 0; i < answerers.getLength(); i++) {
System.out.println("Answerer: " + answerers.item(i).getFirstChild().getNodeValue());
}
Y aquí hay un ejemplo de cómo hacer exactamente lo mismo con Jsoup:
String url = "http://stackoverflow.com/questions/3152138";
Document document = Jsoup.connect(url).get();
Element question = document.select("#question .post-text p").first();
System.out.println("Question: " + question.text());
Elements answerers = document.select("#answers .user-details a");
for (Element answerer : answerers) {
System.out.println("Answerer: " + answerer.text());
}
¿Ves la diferencia? No sólo es menos código, sino que Jsoup también es relativamente fácil de entender si ya tienes experiencia moderada con selectores CSS (por ejemplo, desarrollando sitios web y/o usando jQuery).
Resumen
Los pros y los contras de cada uno deberían quedar suficientemente claros ahora. Si solo desea utilizar la API JAXP estándar para recorrerlo, elija el primer grupo de analizadores mencionado. Hay bastantes de ellos. Cuál elegir depende de las características que proporciona (¿cómo se le facilita la limpieza de HTML? ¿Hay algunos oyentes/interceptores y limpiadores específicos de etiquetas?) y la solidez de la biblioteca (¿con qué frecuencia se actualiza/mantiene/repara? ). Si desea realizar pruebas unitarias de HTML, entonces HtmlUnit es el camino a seguir. Si desea extraer datos específicos del HTML (que suele ser el requisito del mundo real), entonces Jsoup es el camino a seguir.
Este artículo compara ciertos aspectos de los siguientes analizadores:
- NekoHTML
- JTidy
- EtiquetaSopa
- Limpiador HTML
De ninguna manera es un resumen completo y es de 2008. Pero puede que le resulte útil.
Agregue The validator.nu HTML Parser , una implementación del algoritmo de análisis HTML5 en Java, a su lista.
En el lado positivo, está diseñado específicamente para coincidir con HTML5 y es el núcleo del validador de HTML5, por lo que es muy probable que coincida con el comportamiento de análisis del navegador futuro con un grado muy alto de precisión.
En el lado negativo, el análisis heredado de ningún navegador funciona exactamente así y, como HTML5 aún está en borrador, está sujeto a cambios.
En la práctica, estos problemas sólo afectan a casos oscuros y, a todos los efectos prácticos, es un excelente analizador.