2010-01-29 15 views
13

So che questo tipo di domanda deve essere stato chiesto qui prima, ma con la ricerca non ho trovato una soluzione:Rende JavaScript e HTML in (qualsiasi) programma Java (accesso alla struttura del DOM)?

La mia domanda è: Quali sono le migliori librerie Java a "scaricare completamente qualsiasi wepage e rendere il costruito in JavaScript (s) e quindi accedere alla pagina Web renderizzata (che è il DOM-Tree!) in modo programmatico e ottenere l'albero DOM come "HTML-Source".

(Qualcosa di simile a ciò che fa firebug alla fine, rende la pagina e Ho accesso alla struttura ad albero DOM completamente renderizzata, come se la pagina fosse simile al browser! Al contrario, se faccio clic su "mostra sorgente", ottengo solo il codice sorgente JavaScript, che non è quello che voglio. pagina resa ...)

(con il rendering intendo solo rendere l'albero DOM non una resa visiva ...)

Questo non deve essere una singola libreria, è ok per avere diverse librerie che possono realizzare questo insieme (uno molto probabilmente la libreria JavaScript dovrà anche avere un qualche tipo di downloader per rendere completamente qualsiasi JS asincrono ...

Sfondo: Nel " bei vecchi tempi "HttpClient (Apache Library) era tutto il necessario per costruire il proprio crawler molto semplice. (Un sacco di cralwers come Nutch o Heretrix sono ancora costruiti attorno a questo nucleo principale, principalmente incentrato sull'analisi HTML standard, quindi non posso imparare da loro) Il mio problema è che ho bisogno di sottoporre a scansione alcuni siti Web che si basano fortemente su JavaScript e che non riesco ad analizzare con HttpClient poiché ho assolutamente bisogno di eseguire i JavaScripts prima ...

Grazie mille !! Tim

+0

Quando si pronuncia "rendering qualsiasi js asincrono" si intende che la libreria deve avere la capacità di "raschiare" qualsiasi chiamata asincrona effettuata dalla pagina?Ciò sarebbe davvero difficile perché in pratica si cercherebbe di acquisire il contenuto di una pagina dinamica che si aggiorna dopo che la richiesta iniziale è stata completata e talvolta i dati non vengono estratti in modo asincrono finché l'utente non attiva un evento. – bsimic

risposta

4

Questo è un po 'fuori dagli schemi, ma se avete intenzione di correre il codice in un server in cui si ha il controllo completo sopra il vostro ambiente, potrebbe funzionare ...

Installare Firefox (o XulRunner, se si desidera mantenere le cose leggere) sul proprio computer.

Utilizzando il sistema plugin di Firefox, scrivere un piccolo plug-in che carica un determinato URL, attende alcuni secondi, copia il DOM della pagina in una stringa.

da questo plug-in, utilizzare l'API Java LiveConnect (vedere http://jdk6.java.net/plugin2/liveconnect/ e https://developer.mozilla.org/en/LiveConnect) per inviare tale stringa a una funzione statica pubblica in qualche codice Java incorporato, che può eseguire l'elaborazione richiesta o generarne altre codice complicato.

Vantaggi: Si sta utilizzando un browser a cui la maggior parte degli sviluppatori di applicazioni è destinato, pertanto il comportamento osservato dovrebbe essere comparabile. Puoi anche aggiornare il browser lungo il normale percorso di aggiornamento, così la tua biblioteca non diventerà obsoleta al cambiare degli standard HTML.

Svantaggi: È necessario disporre dell'autorizzazione per avviare un'applicazione non headless sul server. Avrai anche la complessità della comunicazione tra processi di cui preoccuparti.

Ho usato l'API di plugin per chiamare Java prima ed è abbastanza fattibile. Se desideri un codice di esempio, dovresti dare un'occhiata al plug-in XQuery: carica il codice XQuery dal DOM, lo passa alla libreria Java Saxon per l'elaborazione, quindi reinserisce il risultato nel browser. Ci sono alcuni dettagli su di esso qui:

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

+0

+1 - Una soluzione su queste linee era già stata avviata una volta, ma sfortunatamente lo sviluppo si è arrestato nel 2008, apparentemente - inserisci [Crowbar] (http://simile.mit.edu/wiki/Crowbar ]): _Il suo scopo è consentire l'esecuzione di scrapers javascript contro un DOM per automatizzare lo scraping di siti Web, evitando tutti i problemi di normalizzazione della sintassi. - Anche [l'integrazione di Java è stata tentata con un certo successo] (http: //www.benjysbrain. com/misc/crowbar /), ma le conclusioni e gli aggiornamenti di Ben stanno evidenziando anche alcuni inconvenienti e problemi: –

+0

Grazie, sì, ho avuto anche questa idea, ma se possibile mi piacerebbe avere una soluzione "senza testa", come il software deve essere eseguito su server con probabilmente nessun sistema X installato ... Ma grazie per i dettagli e le spiegazioni, avrò un aspetto più approfondito se nient'altro: – morja

2

La biblioteca Selenium viene normalmente utilizzato per il test, ma ti dà il controllo remoto della maggior parte dei browser standard (IE, Firefox, ecc), così come un senza testa, del browser modalità libera (usando HtmlUnit). Poiché è destinato alla verifica dell'interfaccia utente tramite scraping della pagina, potrebbe essere utile ai fini dell'utente.

Nella mia esperienza a volte può essere difficile con JavaScript molto lento, ma con un uso attento dei comandi di "attesa" è possibile ottenere risultati abbastanza affidabili.

Ha anche il vantaggio che si può effettivamente guidare la pagina, non solo raschiare. Ciò significa che se si eseguono alcune azioni sulla pagina prima di ottenere i dati desiderati (fare clic sul pulsante di ricerca, fare clic su Avanti, ora scrape), quindi è possibile codificarlo nel processo.

Non so se sarete in grado di ottenere il DOM completo in una forma navigabile da Selenium, ma è fornire il recupero XPath per le varie parti della pagina, che è ciò che normalmente bisogno di un'applicazione raschiante.

+0

Grazie! Il Selenium sembra promettente, ma se voglio a eseguirlo senza testa potrei usare direttamente HtmlUnit. E finora ho avuto alcuni problemi con HtmlUnit. Soprattutto quando si tratta di prestazioni. Daremo un'occhiata più da vicino al Selenium. – morja

2

È possibile utilizzare Java, Groovy con o senza Grails. Quindi utilizzare Webdriver, Selenium, Spock e Geb questi sono a scopo di test, ma le librerie sono utili per il tuo caso. È possibile implementare un crawler che non aprirà una nuova finestra ma solo un runtime di questi browser.

+0

Geb sembra promettente, cercherò di approfondirlo. Grazie! – morja

+0

Sì, avrei dovuto specificare che Geb include tutto quanto sopra :) È davvero un ottimo modo per fare test. – Gepsens

1

Non ho provato questo progetto, ma ho visto diverse implementazioni per nodo. js che includono la manipolazione di javascript dom.

https://github.com/tmpvar/jsdom

3

È possibile utilizzare JavaFX 2 WebEngine. Scarica JavaFX SDK (potresti già averlo se hai installato JDK7u2 o successivo) e prova il codice qui sotto.

Stampa in html con javascript elaborato. Puoi anche decommentare le righe nel mezzo per vedere anche il rendering.

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

Ciao, grazie per la risposta. Ma non sono riuscito a caricare alcuni siti web. Per esempio. Non ho potuto caricare http://maps.google.com/maps/place?cid=4049416522220865697&view=feature&mcsrc=google_reviews&num=10&start=0. Non raggiunge mai il 100%, si blocca a 0. Inoltre, come posso essere sicuro che tutto sia caricato? – morja

+0

è necessario caricare la scena altrimenti non funzionerebbe – DevZer0

+0

è possibile utilizzare un JFrame per rendere il webengine funzionare anche al di fuori di launch (args). Quindi WebLauncher di classe pubblica estende JFrame. Avrai bisogno di evitare i driver Selenium, fanno schifo (perdita, blocco, generazione di eccezioni quando vengono inseriti o elaborati e ogni sorta di assurdità). Inoltre, è necessario rpc su un server WebEngine in quanto vi sono perdite a bizzeffe. Se i tuoi siti non richiedono normalmente SSL e gli errori di connessione sono corretti, Scrapy utilizza il Qt4.8 di quasi 10 anni per farlo con il loro nuovo server JS. Raccomando di riavviare il motore e di passare i cookie di volta in volta. JDK 9 dovrebbe risolvere. –

Problemi correlati