2010-01-29 7 views
13

Sé que este tipo de pregunta debe haber sido formulada anteriormente, pero buscando no encontré una solución:Renderizar JavaScript y HTML en (cualquier) programa Java (Acceso al árbol DOM renderizado)?

Mi pregunta es: ¿cuáles son las mejores bibliotecas de Java para "descargar completamente cualquier página y renderizar el JavaScript incorporado (s) y luego acceda programáticamente a la página web renderizada (que es el DOM-Tree!) y obtenga el Árbol DOM como una "Fuente HTML".

(Algo similar es lo que hace firebug al final, renderiza la página y Obtengo acceso al Árbol DOM completamente renderizado, ¡como se ve la página en el navegador! Por el contrario, si hago clic en "mostrar origen", solo obtengo el código fuente JavaScript. Esto no es lo que quiero. Necesito tener acceso al página renderizada ...)

(con la representación me refiero solamente haciendo que el árbol DOM no una representación visual ...)

Esto no tiene que ser una sola biblioteca, que está bien tener varias bibliotecas que pueden lograr esto juntos (uno descargará, renderizará ...) pero debido a la naturaleza dinámica de JavaScript, es probable que la biblioteca JavaScript también tenga que tener algún tipo de descargador para representar completamente cualquier JS asincrónico ...

Antecedentes: En " buenos días "HttpClient (Biblioteca Apache) era todo lo que se necesitaba para construir tu propio rastreador muy simple. (Muchos editores como Nutch o Heretrix siguen construyendo en torno a este principio básico, centrándose principalmente en el análisis HTML estándar, por lo que no puedo aprender de ellos) Mi problema es que tengo que rastrear algunos sitios web que dependen en gran medida de JavaScript y que no puedo analizar con HttpClient ya que definitivamente necesito ejecutar los JavaScripts antes ...

¡Muchas gracias! Tim

+0

Cuando dice "renderizar js asincrónico" ¿quiere decir que la biblioteca necesita tener la capacidad de "raspar" las llamadas asincrónicas que hace la página?Esto sería realmente difícil porque básicamente trataría de capturar el contenido de una página dinámica que se actualiza después de que se complete la solicitud inicial y, a veces, los datos no se extraen de forma asíncrona hasta que el usuario desencadena un evento. – bsimic

Respuesta

4

Esto es un poco fuera de la caja, pero si usted está planeando en el funcionamiento de su código en un servidor en el que tener un control completo sobre su entorno, podría funcionar ...

Instale Firefox (o XulRunner, si desea mantener las cosas ligeras) en su máquina.

Usando el sistema de complementos de Firefox, escriba un pequeño complemento que toma una URL determinada, espera unos segundos, copia el DOM de la página en una cadena.

de este plugin, utilice la API de Java LiveConnect (ver http://jdk6.java.net/plugin2/liveconnect/ y https://developer.mozilla.org/en/LiveConnect) para empujar esa cadena a través de una función estática pública en algún código Java embebido, que puede hacer el procesamiento requerido en sí o una granja que a poco más código complicado

Beneficios: Está utilizando un navegador al que apuntan la mayoría de los desarrolladores de aplicaciones, por lo que el comportamiento observado debe ser comparable. También puede actualizar el navegador a lo largo de la ruta de actualización normal, por lo que su biblioteca no quedará desactualizada a medida que cambien los estándares HTML.

Desventajas: Deberá tener permiso para iniciar una aplicación no sin cabeza en su servidor. También tendrá que preocuparse por la complejidad de la comunicación entre procesos.

He utilizado la API de complemento para llamar a Java antes, y es bastante factible. Si desea algún código de muestra, debe echar un vistazo al complemento de XQuery: carga el código de XQuery desde el DOM, lo pasa a la biblioteca de Java Saxon para su procesamiento y luego lo devuelve al navegador. Hay algunos detalles al respecto aquí:

https://developer.mozilla.org/en/XQuery

+0

+1 - Una solución a lo largo de estas líneas ya se había iniciado una vez, pero desafortunadamente el desarrollo se estancó en 2008, al parecer - ingrese [Crowbar] (http://simile.mit.edu/wiki/Crowbar ]): _su propósito es permitir la ejecución de raspadores de javascript contra un DOM para automatizar el raspado de sitios web, pero evitando todos los problemas de normalización de la sintaxis. - Incluso una [integración de Java se ha intentado con cierto éxito] (http: //www.benjysbrain. com/misc/crowbar /), pero la conclusión y las actualizaciones de Ben destacan algunos inconvenientes y problemas. –

+0

Gracias, sí, también tuve esta idea. Pero si es posible, me gustaría tener una solución "sin cabeza", ya que el software tiene que ejecutarse en servidores con posiblemente ningún sistema X instalado ... Pero gracias por los detalles y las explicaciones, lo examinaré más a fondo si no aparece nada más. – morja

2

La biblioteca Selenium se utiliza normalmente para las pruebas, pero le otorga el mando a distancia de la mayoría de los navegadores estándar (IE, Firefox, etc), así como un sin cabeza, el navegador modo libre (usando HtmlUnit). Como está destinado a la verificación de la interfaz de usuario por raspado de páginas, puede ser útil para sus propósitos.

En mi experiencia, a veces puede tener problemas con JavaScript muy lento, pero con el uso cuidadoso de los comandos de "espera" puede obtener resultados bastante confiables.

También tiene la ventaja de que puede conducir la página, no solo rasparla. Eso significa que si realiza algunas acciones en la página antes de llegar a los datos que desea (haga clic en el botón de búsqueda, haga clic en siguiente, ahora raspar), luego puede codificar eso en el proceso.

No sé si va a ser capaz de obtener el DOM completo en una forma navegable desde selenio, pero lo hace proporcionar recuperación de XPath para las diferentes partes de la página, que es lo que se suele necesidad de una aplicación de raspado.

+0

Gracias Selenio parece prometedor, pero si quiero a ejecutarlo sin cabeza podría usar directamente HtmlUnit. Y hasta ahora tuve algunos problemas con HtmlUnit. Especialmente cuando se trata de rendimiento. Voy a echar un vistazo más de cerca al Selenio. – morja

2

Puede usar Java, Groovy con o sin Grails. Luego, use Webdriver, Selenium, Spock y Geb; estos son para fines de prueba, pero las bibliotecas son útiles para su caso. Puede implementar un rastreador que no abrirá una nueva ventana, sino solo un tiempo de ejecución de estos ya sea el navegador.

+0

Geb parece prometedor, lo investigaré más a fondo. ¡Gracias! – morja

+0

Sí, debería haber especificado que Geb incluye todo lo anterior :) Realmente es una nueva forma de hacer pruebas. – Gepsens

3

Puede utilizar JavaFX 2 WebEngine. Descargue JavaFX SDK (puede que ya lo tenga si instaló JDK7u2 o posterior) y pruebe el código a continuación.

Imprimirá html con javascript procesado. Puede descomentar líneas en el medio para ver la representación también.

public class WebLauncher extends Application { 

    @Override 
    public void start(Stage stage) { 
     final WebView webView = new WebView(); 
     final WebEngine webEngine = webView.getEngine(); 
     webEngine.load("http://stackoverflow.com"); 
     //stage.setScene(new Scene(webView)); 
     //stage.show(); 

     webEngine.getLoadWorker().workDoneProperty().addListener(new ChangeListener<Number>() { 
      @Override 
      public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { 
       if (newValue.intValue() == 100 /*percents*/) { 
        try { 
         org.w3c.dom.Document doc = webEngine.getDocument(); 
         new XMLSerializer(System.out, new OutputFormat(doc, "UTF-8", true)).serialize(doc); 
        } catch (IOException ex) { 
         ex.printStackTrace(); 
        } 
       } 
      } 
     }); 

    } 

    public static void main(String[] args) { 
     launch(); 
    } 

} 
+0

Hola, gracias por esa respuesta. Pero no pude cargar algunos sitios web. P.ej. No pude cargar http://maps.google.com/maps/place?cid=4049416522220865697&view=feature&mcsrc=google_reviews&num=10&start=0. Nunca llega al 100 por ciento, se cuelga a 0. Además, ¿cómo puedo asegurarme de que todo esté cargado? – morja

+0

necesita cargar la escena o de lo contrario no funcionaría – DevZer0

+0

puede usar un JFrame para hacer que la página web funcione fuera del inicio (args) también. Así que el WebLauncher de clase pública extiende JFrame. Tendrá que evitar los controladores de selenio, chupan (gotean, cuelgan, lanzan excepciones cuando se enhebran o procesan, y todo tipo de tonterías). Además, necesitará rpc a un servidor de WebEngine ya que hay muchas fugas. Si sus sitios normalmente no demandan SSL actualizado y las fallas de conexión están bien para usted, Scrapy utiliza el Qt4.8 de casi 10 años para hacer esto con su nuevo servidor JS. Recomiendo reiniciar el motor y pasar cookies de vez en cuando. JDK 9 debería arreglarlo. –

Cuestiones relacionadas