HtmlUnit配置失败求助:无法找到‘earth’模块
嘿,我来帮你捋捋这个头疼的问题——HtmlUnit抛出的ScriptException明明白白指向找不到名为earth的模块,这大概率是页面加载的JS代码里引入了这个自定义模块,但HtmlUnit的JS环境没法正确识别或者加载它。下面给你几个实打实的排查和解决方向:
1. 先确认模块的加载逻辑
首先得搞清楚目标页面里earth模块是怎么被引入的:
- 如果是用
import/require这类ES模块语法引入的,HtmlUnit对ES模块的支持需要额外配置,你得确保开启了ES模块相关支持:WebClient webClient = new WebClient(); webClient.getOptions().setJavaScriptEnabled(true); // 先临时关闭脚本错误抛出,方便调试 webClient.getOptions().setThrowExceptionOnScriptError(false); // 启用ES6+语法支持 webClient.getJavaScriptEngine().getContextFactory().addContextListener((cx, context) -> { cx.setLanguageVersion(Context.VERSION_ES6); }); - 如果是页面用了自定义的模块加载器来加载
earth,那HtmlUnit大概率识别不了这个自定义逻辑,这时候就得手动模拟模块加载或者注入模块了。
2. 手动注入模拟模块
如果earth是页面依赖的自定义模块,你可以在HtmlUnit加载页面之前,手动给JS环境注入一个模拟的earth模块,让它能被找到:
webClient.addWebWindowListener(new WebWindowListener() { @Override public void webWindowOpened(WebWindowEvent event) {} @Override public void webWindowContentChanged(WebWindowEvent event) { WebWindow window = event.getWebWindow(); if (window.getEnclosedPage() != null) { // 注入模拟的earth模块,按需添加模块需要的方法/属性 window.getScriptableObject().defineProperty("earth", new ScriptableObject() { public void initMap() { // 模拟模块内的方法实现 } }, ScriptableObject.DONTENUM); } } @Override public void webWindowClosed(WebWindowEvent event) {} });
3. 排查资源加载是否异常
有时候模块找不到,是因为HtmlUnit没正确加载到earth对应的JS文件。你可以开启HtmlUnit的日志,看看资源加载的细节:
java.util.logging.Logger.getLogger("com.gargoylesoftware.htmlunit").setLevel(java.util.logging.Level.FINE);
通过日志就能看到哪些资源加载失败,是不是earth模块的JS文件路径不对、被拦截了,或者根本没请求到。
补充:你的错误信息解析
你贴的错误片段能帮我们更精准定位问题:
======= EXCEPTION START ========
Exception class=[net.sourceforge.htmlunit.corejs.javascript.WrappedException]
com.gargoylesoftware.htmlunit.ScriptException: Wrapped com.gargoylesoftware.htmlunit.ScriptException: Error: Module: 'earth' not found! ( https://www.g...
这个错误说明HtmlUnit在执行页面JS时,遇到了模块加载失败的情况,要么是JS引擎解析不了模块的引入路径,要么是模块对应的文件压根没被加载成功。
要是你能补充下项目结构截图(或者描述下HtmlUnit的配置代码、目标页面里引入earth的具体代码),还能进一步缩小排查范围哦!
内容的提问来源于stack exchange,提问作者max

