scraping read parser parse online java xpath html-parsing

java - read - parse html online



Usando XPath Contiene contra HTML en Java (1)

Estoy raspando los valores de las páginas HTML usando XPath dentro de un programa java para llegar a una etiqueta específica y, ocasionalmente, utilizando expresiones regulares para limpiar los datos que recibo.

Después de algunas investigaciones, llegué a HTML Cleaner ( http://htmlcleaner.sourceforge.net/ ) como la forma más confiable de analizar HTML en bruto en un buen formato XML. Sin embargo, HTML Cleaner solo es compatible con XPath 1.0 y me parece que necesito funciones como ''contiene''. Por ejemplo, en esta pieza de XML:

<div> <td id=''1234 foo 5678''>Hello</td> </div>

Me gustaría poder obtener el texto ''Hola'' con la siguiente XPath:

//div/td[contains(@id, ''foo'')]/text()

¿Hay alguna manera de obtener esta funcionalidad? Tengo varias ideas, pero preferiría no reinventar la rueda si no fuera necesario:

  • Si hay una manera de llamar a evalXPath de HTML Cleaner y devolver un TagNode (que no he encontrado), puedo usar un serializador XML en el TagNode devuelto y encadenar XPaths para lograr la funcionalidad deseada.
  • Podría usar HTML Cleaner para limpiar a XML, serializarlo de nuevo a una cadena y usarlo con otra biblioteca XPath, pero no puedo encontrar un buen evaluador XPath de java que funcione en una cadena.
  • Usando funciones de TagNode como getElementsByAttValue, esencialmente podría recrear la evaluación de XPath e insertarla en la funcionalidad de contenidos usando String.contains

Pregunta corta: ¿Hay alguna forma de usar XPath contenida en HTML dentro de una biblioteca Java existente?


Con respecto a este:

Podría usar HTML Cleaner para limpiar a XML, serializarlo de nuevo a una cadena y usarlo con otra biblioteca XPath, pero no puedo encontrar un buen evaluador XPath de java que funcione en una cadena.

Esto es exactamente lo que haría (excepto que no necesita operar en una cadena (ver más abajo)).

Muchos analizadores de HTML intentan hacer demasiado . HTMLCleaner, por ejemplo, no implementa correctamente / completamente la especificación XPath 1.0 ( contains (por ejemplo) w3.org/TR/xpath/#function-contains ). La buena noticia es que no lo necesitas. Todo lo que necesita de HTMLCleaner es para que analice la entrada con formato incorrecto. Una vez que haya hecho eso, es mejor usar las interfaces XML estándar para lidiar con el documento resultante (ahora bien formado).

Primero convierta el documento en un org.w3c.dom.Document estándar como este:

TagNode tagNode = new HtmlCleaner().clean( "<div><table><td id=''1234 foo 5678''>Hello</td>"); org.w3c.dom.Document doc = new DomSerializer( new CleanerProperties()).createDOM(tagNode);

Y luego use las interfaces estándar de JAXP para consultarlas:

XPath xpath = XPathFactory.newInstance().newXPath(); String str = (String) xpath.evaluate("//div//td[contains(@id, ''foo'')]/text()", doc, XPathConstants.STRING); System.out.println(str);

Salida:

Hello