HtmlUnit click()事件不起作用,并在Java中触发ClassCastException

时间:2017-04-13 14:08:02

标签: java webclient htmlunit

我在Java应用程序中使用HtmlUnit来加载网页并提交其表单。我得到表单和提交输入没有任何问题,但是当我在该元素上调用函数click()时,它会触发Cast异常并且似乎不执行click事件。这是我的webClient配置:

this.webClient = new WebClient(BrowserVersion.CHROME);

webClient.getOptions().setJavaScriptEnabled(true);
webClient.getOptions().setThrowExceptionOnScriptError(true);
webClient.getOptions().setCssEnabled(false);
webClient.setAjaxController(new NicelyResynchronizingAjaxController());
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setRedirectEnabled(true);

final HtmlPage jobPage = webClient.getPage("https://mySite/j#edit-job?id="+job.getJobID());
webClient.waitForBackgroundJavaScript(15000);

以下是页面加载和输入选择的代码:

HtmlForm form = jobPage.getFormByName("");
HtmlSubmitInput submit = null;
final List<HtmlInput> inputs = form.getInputsByName("");

for(HtmlInput input : inputs){

    if(input.getAttribute("id").equals("postFormSubmit")){
        submit = (HtmlSubmitInput)input;
        break;
    }
}


if(submit != null){
    try {
        HtmlPage confirmUpdate = submit.click();
        webClient.waitForBackgroundJavaScript(15000);

        System.out.println("response : \n\n");
        System.out.println(confirmUpdate.asText());
        System.out.println("end response");

    }
    catch(Exception e){
        e.printStackTrace();
    }
}
else {
    System.out.println("submit input non trouvé");
}

我还尝试通过以下方式手动执行一些javascript:

jobPage.executeJavascript("javascript:document.getElementById('postFormSubmit').click();");

但我得到了同样的例外:

INFOS: Caught script exception
======= EXCEPTION START ========
Exception class=[java.lang.ClassCastException]
com.gargoylesoftware.htmlunit.ScriptException: com.gargoylesoftware.htmlunit.javascript.host.html.HTMLInputElement cannot be cast to com.gargoylesoftware.htmlunit.html.HtmlElement
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:898)
    at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:637)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:518)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.callFunction(JavaScriptEngine.java:827)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.callFunction(JavaScriptEngine.java:799)
    at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScriptFunctionIfPossible(HtmlPage.java:2470)
    at com.gargoylesoftware.htmlunit.javascript.host.event.EventListenersContainer.executeEventListeners(EventListenersContainer.java:259)
    at com.gargoylesoftware.htmlunit.javascript.host.event.EventListenersContainer.executeBubblingListeners(EventListenersContainer.java:325)
    at com.gargoylesoftware.htmlunit.javascript.host.event.EventTarget.fireEvent(EventTarget.java:188)
    at com.gargoylesoftware.htmlunit.html.DomElement$2.run(DomElement.java:1389)
    at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:637)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:518)
    at com.gargoylesoftware.htmlunit.html.DomElement.fireEvent(DomElement.java:1394)
    at com.gargoylesoftware.htmlunit.html.DomElement.fireEvent(DomElement.java:1362)
    at com.gargoylesoftware.htmlunit.html.HtmlForm.submit(HtmlForm.java:116)
    at com.gargoylesoftware.htmlunit.html.HtmlSubmitInput.doClickStateUpdate(HtmlSubmitInput.java:90)
    at com.gargoylesoftware.htmlunit.html.DomElement.click(DomElement.java:999)
    at com.gargoylesoftware.htmlunit.html.DomElement.click(DomElement.java:944)
    at com.gargoylesoftware.htmlunit.html.DomElement.click(DomElement.java:884)
    at com.gargoylesoftware.htmlunit.html.DomElement.click(DomElement.java:865)
    at model.IndeedManip$2.run(IndeedManip.java:309)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassCastException: com.gargoylesoftware.htmlunit.javascript.host.html.HTMLInputElement cannot be cast to com.gargoylesoftware.htmlunit.html.HtmlElement
    at com.gargoylesoftware.htmlunit.javascript.host.dom.AbstractList.addElementIds(AbstractList.java:541)
    at com.gargoylesoftware.htmlunit.javascript.host.dom.AbstractList.getIds(AbstractList.java:523)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.enumChangeObject(ScriptRuntime.java:2235)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.enumInit(ScriptRuntime.java:2136)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1740)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.java:800)
    at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:105)
    at net.sourceforge.htmlunit.corejs.javascript.NativeArray.iterativeMethod(NativeArray.java:1694)
    at net.sourceforge.htmlunit.corejs.javascript.NativeArray.execIdCall(NativeArray.java:405)
    at net.sourceforge.htmlunit.corejs.javascript.IdFunctionObject.call(IdFunctionObject.java:94)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.applyOrCall(ScriptRuntime.java:2575)
    at net.sourceforge.htmlunit.corejs.javascript.BaseFunction.execIdCall(BaseFunction.java:321)
    at net.sourceforge.htmlunit.corejs.javascript.IdFunctionObject.call(IdFunctionObject.java:94)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1540)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.java:800)
    at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:105)
    at net.sourceforge.htmlunit.corejs.javascript.NativeArray.iterativeMethod(NativeArray.java:1694)
    at net.sourceforge.htmlunit.corejs.javascript.NativeArray.execIdCall(NativeArray.java:405)
    at net.sourceforge.htmlunit.corejs.javascript.IdFunctionObject.call(IdFunctionObject.java:94)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.applyOrCall(ScriptRuntime.java:2575)
    at net.sourceforge.htmlunit.corejs.javascript.BaseFunction.execIdCall(BaseFunction.java:321)
    at net.sourceforge.htmlunit.corejs.javascript.IdFunctionObject.call(IdFunctionObject.java:94)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1540)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.java:800)
    at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:105)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.doTopCall(ContextFactory.java:416)
    at com.gargoylesoftware.htmlunit.javascript.HtmlUnitContextFactory.doTopCall(HtmlUnitContextFactory.java:292)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3264)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$4.doRun(JavaScriptEngine.java:820)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:883)
    ... 27 more
Enclosed exception: 
java.lang.ClassCastException: com.gargoylesoftware.htmlunit.javascript.host.html.HTMLInputElement cannot be cast to com.gargoylesoftware.htmlunit.html.HtmlElement
    at com.gargoylesoftware.htmlunit.javascript.host.dom.AbstractList.addElementIds(AbstractList.java:541)
    at com.gargoylesoftware.htmlunit.javascript.host.dom.AbstractList.getIds(AbstractList.java:523)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.enumChangeObject(ScriptRuntime.java:2235)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.enumInit(ScriptRuntime.java:2136)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1740)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.java:800)
    at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:105)
    at net.sourceforge.htmlunit.corejs.javascript.NativeArray.iterativeMethod(NativeArray.java:1694)
    at net.sourceforge.htmlunit.corejs.javascript.NativeArray.execIdCall(NativeArray.java:405)
    at net.sourceforge.htmlunit.corejs.javascript.IdFunctionObject.call(IdFunctionObject.java:94)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.applyOrCall(ScriptRuntime.java:2575)
    at net.sourceforge.htmlunit.corejs.javascript.BaseFunction.execIdCall(BaseFunction.java:321)
    at net.sourceforge.htmlunit.corejs.javascript.IdFunctionObject.call(IdFunctionObject.java:94)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1540)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.java:800)
    at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:105)
    at net.sourceforge.htmlunit.corejs.javascript.NativeArray.iterativeMethod(NativeArray.java:1694)
    at net.sourceforge.htmlunit.corejs.javascript.NativeArray.execIdCall(NativeArray.java:405)
    at net.sourceforge.htmlunit.corejs.javascript.IdFunctionObject.call(IdFunctionObject.java:94)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.applyOrCall(ScriptRuntime.java:2575)
    at net.sourceforge.htmlunit.corejs.javascript.BaseFunction.execIdCall(BaseFunction.java:321)
    at net.sourceforge.htmlunit.corejs.javascript.IdFunctionObject.call(IdFunctionObject.java:94)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1540)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.java:800)
    at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:105)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.doTopCall(ContextFactory.java:416)
    at com.gargoylesoftware.htmlunit.javascript.HtmlUnitContextFactory.doTopCall(HtmlUnitContextFactory.java:292)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3264)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$4.doRun(JavaScriptEngine.java:820)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:883)
    at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:637)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:518)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.callFunction(JavaScriptEngine.java:827)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.callFunction(JavaScriptEngine.java:799)
    at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScriptFunctionIfPossible(HtmlPage.java:2470)
    at com.gargoylesoftware.htmlunit.javascript.host.event.EventListenersContainer.executeEventListeners(EventListenersContainer.java:259)
    at com.gargoylesoftware.htmlunit.javascript.host.event.EventListenersContainer.executeBubblingListeners(EventListenersContainer.java:325)
    at com.gargoylesoftware.htmlunit.javascript.host.event.EventTarget.fireEvent(EventTarget.java:188)
    at com.gargoylesoftware.htmlunit.html.DomElement$2.run(DomElement.java:1389)
    at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:637)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:518)
    at com.gargoylesoftware.htmlunit.html.DomElement.fireEvent(DomElement.java:1394)
    at com.gargoylesoftware.htmlunit.html.DomElement.fireEvent(DomElement.java:1362)
    at com.gargoylesoftware.htmlunit.html.HtmlForm.submit(HtmlForm.java:116)
    at com.gargoylesoftware.htmlunit.html.HtmlSubmitInput.doClickStateUpdate(HtmlSubmitInput.java:90)
    at com.gargoylesoftware.htmlunit.html.DomElement.click(DomElement.java:999)
    at com.gargoylesoftware.htmlunit.html.DomElement.click(DomElement.java:944)
    at com.gargoylesoftware.htmlunit.html.DomElement.click(DomElement.java:884)
    at com.gargoylesoftware.htmlunit.html.DomElement.click(DomElement.java:865)
    at model.IndeedManip$2.run(IndeedManip.java:309)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
== CALLING JAVASCRIPT ==
  function (c) {
      return a.call(b.src, b.Mh, c);
  }
======= EXCEPTION END ========

据说它是一个Casting异常,但我没有进行任何强制转换,错误位于click()事件的行。

如果您知道使用HtmlUnit触发点击事件的另一种方式,请告诉我。

2 个答案:

答案 0 :(得分:0)

这只是通过提交1409214093修复的。

您可以从here获取最新版本。

测试用例是:

/**
 * @throws Exception on test failure
 */
@Test
@Alerts(DEFAULT = "0,1,2,3,4,5,entries,forEach,item,keys,length,values",
        IE = "0,1,2,3,4,5,item,length")
public void iterator() throws Exception {
    final String html = "<html><head><title>test</title>\n"
            + "<script>\n"
            + "  function test() {\n"
            + "    var all = [];\n"
            + "    for (var i in document.querySelectorAll('*')) {\n"
            + "      all.push(i);\n"
            + "    }\n"
            + "    all.sort(sortFunction);\n"
            + "    alert(all);\n"
            + "  }\n"
            + "  function sortFunction(s1, s2) {\n"
            + "    return s1.toLowerCase() > s2.toLowerCase() ? 1 : -1;\n"
            + "  }\n"
            + "</script>\n"
            + "</head><body onload='test()'>\n"
            + "  <div>/div>\n"
            + "</body></html>";

    loadPageWithAlerts2(html);
}

答案 1 :(得分:0)

感谢Ahmed Ashour,这个函数不再触发异常,但我的表单从未被HtmlUnit提交过。

最后我切换到Selenium,这对于javascript执行更有效。我建议任何一个人在网络抓取应用程序上提交ajax驱动的表单以使用Selenium