2 votes

Exécution de HtmlUnit via Tomcat 7

Je tente d'utiliser HTMLUnit pour produire des instantanés HTML exploitables par les internautes de nos pages ajax (comme suggéré par https://developers.google.com/webmasters/ajax-crawling/ ). L'idée est de créer une fonctionnalité qui permette aux entreprises de créer des instantanés soit par le biais d'un service régulier programmé, soit à leur gré.

J'ai écrit une classe principale POC rapide pour tester la théorie et cela a fonctionné comme prévu (lorsque nous visualisons la source, nous pouvons voir toutes les données nécessaires pour le robot d'exploration Google que nous ne pouvions pas voir avant). Je suis maintenant en train d'intégrer ceci dans notre application qui tourne sur Tomcat 7 et j'ai un problème pour télécharger le jquery.js de Google avec les messages de log suivants

2013-03-15 18:10:38,071 ERROR [author->taskExecutor-1] com.gargoylesoftware.htmlunit.html.HtmlPage       : Error loading JavaScript from [https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js].
javax.net.ssl.SSLException: hostname in certificate didn't match: <ajax.googleapis.com/173.194.67.95> != <*.googleapis.com> OR <*.googleapis.com> OR <googleapis.com>
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:228)
at org.apache.http.conn.ssl.BrowserCompatHostnameVerifier.verify(BrowserCompatHostnameVerifier.java:54)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:149)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:130)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:397)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:495)
at org.apache.http.conn.scheme.SchemeSocketFactoryAdaptor.connectSocket(SchemeSocketFactoryAdaptor.java:62)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:148)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:150)

...

Pour cette raison, l'ajax n'est pas exécuté et le snapshot ne contient pas les données dans la source de vue que nous souhaitons. Quelqu'un a-t-il une idée de la raison pour laquelle cela se produit dans ma version Tomcat du code et non dans ma classe principale autonome ? Les deux versions sont exécutées sur ma machine locale, l'une est simplement dans Tomcat (v7) et l'autre comme une application Java. Les deux versions ont les mêmes includes Maven (voir en bas).

Note : J'ai essayé de spécifier une version du navigateur lors de l'installation de l'application. WebClient client = new WebClient(BrowserVersion.FIREFOX_17); car j'ai lu que cela produisait de meilleurs résultats (désolé, je ne me souviens plus du lien). Encore une fois, cela fonctionne bien dans le POC, mais lorsque je l'exécute dans Tomcat, je vois le log "Instatiating Web Client" mais peu importe le temps que j'attends, il n'arrive jamais à "Client Instatiated" ou ne lève aucune exception. Je ne sais pas si cela a quelque chose à voir avec le fait de ne pas pouvoir télécharger le jqeury.js, car il fonctionne toujours dans le POC sans que la version du navigateur soit spécifiée.

Voici ma méthode principale POC Java qui fonctionne

        OutputStreamWriter writer = null;

        try {
            final WebClient webClient = new WebClient();
            webClient.getOptions().setThrowExceptionOnScriptError(false);
            webClient.getOptions().setPrintContentOnFailingStatusCode(false);
            final HtmlPage page = (HtmlPage)webClient.getPage("http://myurl.com");

            webClient.waitForBackgroundJavaScript(1500);

            File file = new File("C:\\test.html");
            FileUtils.touch(file);

            writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
            writer.write(page.asXml());
            writer.flush();

        } catch (MalformedURLException mue) {
            System.out.println("MalformedURL exception");
        } catch (IOException ioe) {
            System.out.println("IOException occurred " +  ioe.getMessage());
        } finally {
            IOUtils.closeQuietly(writer);
        }

Voici ma version intégrée

        /* Entry point for the generation */
     public void generate() {

        log.info("Beginning snapshot generation...");

        try {

            // Get the URLS
            log.info("Retrieving list of page urls");
            List<String> pageUrls = getUrlList();
            log.info("Found {} urls to generate", pageUrls.size());

            // For every url we have generate a snapshot
            for (String pageUrl: pageUrls) {
                takeSnapshot(pageUrl);
            }
            log.info("Finished generating snapshots!");
        } catch (Exception e) {
            log.error("Exception caught while generating snapshot", e);
        }
    }

    /**
     * Take the HTML snapshot of the url and output to the snapshot directory
     */
    private void takeSnapshot(String pagePath) {
        try {
            String fullOutputFilePath = config.getHtmlSnapshotDirectory() + File.separator
                                                        + pagePath + File.separator + HTML_SNAPSHOT_FILE_NAME;
            String pageUrl = "http://myurl.com" + pagePath;

            log.debug("Instantiating Web Client...");
            final WebClient webClient = new WebClient();
            log.debug("Client instantiated");
            webClient.getOptions().setThrowExceptionOnScriptError(false);
            webClient.getOptions().setPrintContentOnFailingStatusCode(false);
            final HtmlPage page = (HtmlPage)webClient.getPage(pageUrl);

            webClient.waitForBackgroundJavaScript(1500);

            snapshotFile = new File(fullOutputFilePath);
            FileUtils.touch(snapshotFile);

            writer = new OutputStreamWriter(new FileOutputStream(snapshotFile), "UTF-8");
            writer.write(page.asXml());
            writer.flush();
        } catch (MalformedURLException mue) {
            System.out.println("MalformedURL exception");
        } catch (IOException ioe) {
            System.out.println("IOException occurred " +  ioe.getMessage());
        } finally {
            IOUtils.closeQuietly(writer);
        }
    }

Dépendances Maven

        <dependency>
            <groupId>net.sourceforge.htmlunit</groupId>
            <artifactId>htmlunit</artifactId>
            <version>2.12</version>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.2.3</version>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.3-alpha1</version>
        </dependency>

Merci à tous ! !!

1voto

DecafCoder Points 91

Donc, en ajoutant webClient.getOptions().setUseInsecureSSL(true); était la clé pour résoudre ce problème. Cependant, j'ai dû utiliser la version dépréciée webClient.setUseInsecureSSL(true); .

Je ne sais pas pourquoi la version la plus récente ne fonctionne pas lorsqu'elle est exécutée dans Tomcat, mais elle a réglé le problème. Si quelqu'un peut me donner une idée de la raison, ce serait formidable. Je ne comprends toujours pas pourquoi le réglage de BrowserVersion lors de l'exécution de Tomcat provoque l'arrêt de l'application. J'ai demandé à la liste de diffusion HtmlUnit des réponses à ces questions.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X