HtmlUnit提供了优秀的JavaScript解决方案,通过该框架模拟浏览器,可以执行相应的JavaScript方法并获取执行后的结果。
然而,遇到的问题也蛮多,不过总有解决方案。
比如说http://xxx.xx.com中有一段JavaScript有错误,由于HtmlUnit太尽责了,给了我们两种选择:1. 抛出异常(大家可以看看源码,跑异常其实就是返回的ScriptResult对象为null);2. 忽略异常,但是打印一大堆日志.....我不知道你们受不受得了,反正我受不了,动手解决呗
做点操作:
final WebClient webClient = new WebClient(BrowserVersion.getDefault());
webClient.getOptions().setCssEnabled(false);//忽略Css
webClient.getOptions().setJavaScriptEnabled(true);//忽略JavaScript
webClient.getOptions().setThrowExceptionOnScriptError(false);//如果JavaScript有错误是否抛出,这里的抛出指的是下面获取到的ScriptResult对象为空
webClient.setJavaScriptEngine(new MyJavaScriptEngine(webClient));//自定义JavaScript引擎,有js错误不打印
其中webClient.setJavaScriptEngine(new MyJavaScriptEngine(webClient));//自定义JavaScript引擎,有js错误不打印这个是重头戏,自定义一个MyJavaScriptEngine.java类,代码如下:
import com.gargoylesoftware.htmlunit.InteractivePage;
import com.gargoylesoftware.htmlunit.ScriptException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine;
import com.gargoylesoftware.htmlunit.javascript.JavaScriptErrorListener;
import com.gargoylesoftware.htmlunit.javascript.host.Window;
/**
* 自定义JavaScript解析器(目的是为了不打印js存在的错误到日志)
* @author 小风
* @datetime 2016年6月23日 下午10:19:40
*/
public class MyJavaScriptEngine extends JavaScriptEngine{
public MyJavaScriptEngine(WebClient webClient) {
super(webClient);
}
@Override
protected void handleJavaScriptException(final ScriptException scriptException, final boolean triggerOnError) {
// Trigger window.onerror, if it has been set.
final InteractivePage page = scriptException.getPage();
if (triggerOnError && page != null) {
final WebWindow window = page.getEnclosingWindow();
if (window != null) {
final Window w = (Window) window.getScriptableObject();
if (w != null) {
try {
w.triggerOnError(scriptException);
}
catch (final Exception e) {
handleJavaScriptException(new ScriptException(page, e, null), false);
}
}
}
}
final JavaScriptErrorListener javaScriptErrorListener = getWebClient().getJavaScriptErrorListener();
if (javaScriptErrorListener != null) {
javaScriptErrorListener.scriptException(page, scriptException);
}
// Throw a Java exception if the user wants us to.
if (getWebClient().getOptions().isThrowExceptionOnScriptError()) {
throw scriptException;
}
// Log the error; ScriptException instances provide good debug info.
// LOG.info("Caught script exception", scriptException);
}
}
最后一行注掉就问题解决了,简单粗暴。还是那句话,欢迎拍砖~