首页 > 解决方案 > 在 htmlunit 中设置 Javascript 超时的问题

问题描述

我正在开发一个点击多个 URL 并每分钟抓取其页面的项目(使用线程池完成)。我为此使用 Htmlunit – 2.20。但是,超时功能不能正确地满足我的目的。

首先,我使用了 WebClient.setTimeout() ,它被使用了两次,一次用于套接字连接,另一次用于数据检索。它为获取每个单独的 .js 脚本创建了新的套接字连接,因此违背了我为整个页面连接和获取过程设置总体超时的目的。其次,我也在使用 webClient.setJavaScriptTimeout() 但这也为每个 js 脚本执行设置了执行超时,这再次违背了我的 Javascript 整体超时的目的。我也使用了 webClient.waitForBackgroundJavaScript() 但即使在指定的超时之后它也不会停止 Javascript 的执行。

有人可以在这里帮助我设置 Javascript 执行的总体超时。我也尝试过使用 Java 的 Future 接口并为页面获取设置超时,但限制是它为此执行创建了一个子线程。服务本身在线程池上运行,每个 URL 获取发生在不同的线程上。如果我为线程池中的每个线程创建一个子线程,它会增加内存消耗。对此或如何衡量内存消耗增加的任何想法都将非常有帮助。任何帮助表示赞赏。

public String loadDocument(String url) {
        try {

            String content;

            webClient.setAjaxController(new NicelyResynchronizingAjaxController());
            request = new WebRequest(new URL(url));
            response = webClient.loadWebResponse(request);
            webClient.waitForBackgroundJavaScript(JS_TIMEOUT);
            webClient.setJavaScriptTimeout(JS_TIMEOUT);
            page = webClient.loadWebResponseInto(response, webClient.getCurrentWindow());
            Callable<Page> task = () -> {
                page = webClient.loadWebResponseInto(response, webClient.getCurrentWindow());
                return page;
             };
            future = executor.submit(task);
            log.info("Thread count after submitting task "+Thread.activeCount());
            page = future.get(JS_TIMEOUT, TimeUnit.SECONDS);
            if (page instanceof TextPage) {
                content = ((TextPage) page).getContent();
            }
            else {
                content = ((HtmlPage) page).asXml();
            }
            log.info("Successfully retrieved content");

            if (log.isTraceEnabled()) {
                log.trace("Response content:\n " + content);
            }
            return content;
        }
        catch (TimeoutException e)
        {
            log.info("Timed out");
            future.cancel(true);
            return response.getContentAsString();
        }
        catch (Exception e) {
            e.printStackTrace();
            System.out.println("Failed to retrieve content because of exception "+e.getCause());
            return null;
        }
        finally {
            log.info("Closing web client");
            log.info("Memory Used in kilo bytes"+ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed()/1024);
            webClient.close();
            executor.shutdown();
        }
    }

标签: javascriptmemorytimeoutthreadpoolhtmlunit

解决方案


推荐阅读