javascript - 在 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();
}
}
解决方案
推荐阅读
- java - 使用参数更新 JPA Spring
- wordpress - Woocommerce 多种变体 - 删除逻辑控制
- c++ - C++条件变量notify_one:释放锁之前还是之后?
- android - 同一应用中的 Google RealTime dB 和 Firestore
- azure - 使用 B2C 租户域时,使用 Azure AD B2C 保护的 Azure 函数返回未经授权
- python - 如何在大量日志文件中搜索 Python 中的特定关键字?
- php - 如何在mysql中以Implode形式插入数组值
- php - PHP Snippet - Edge/Firefox 上的 WordPress 问题
- python - 带列表的字母计数器
- mysql - 将 SQL 查询转换为 mysql 查询时出错