Подтвердить что ты не робот

Как преодолеть исключение HTMLUnit ScriptException?

У меня возникла проблема с строкой кода, которая, вероятно, вызывает некоторые функции js e couse, исключение, как я могу это исправить?

box.setText(link.toString());
client.waitForBackgroundJavaScriptStartingBefore(10000);
box.dblClick(); //this line cause the exception

Exception in thread "main" ======= EXCEPTION START ========
EcmaError: lineNumber=[0] column=[0] lineSource=[function () {] name=[ReferenceError] sourceName=[onclick event for HtmlDivision[<div class="_119 stat_elem focus_target mtm mbl _5bsm _6dh _51z6" id="u_0_k" data-location="maincolumn" onclick="Bootloader.loadComponents(&quot;ComposerXControllerBootload&quot;, emptyFunction);">] in https://www.facebook.com/?_fb_noscript=1] message=[ReferenceError: "Bootloader" is not defined.]
com.gargoylesoftware.htmlunit.ScriptException: ReferenceError: "Bootloader" is not defined.
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:684)
    at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:602)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:507)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.callFunction(JavaScriptEngine.java:616)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.callFunction(JavaScriptEngine.java:591)
    at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScriptFunctionIfPossible(HtmlPage.java:985)
    at com.gargoylesoftware.htmlunit.javascript.host.EventListenersContainer.executeEventHandler(EventListenersContainer.java:210)
    at com.gargoylesoftware.htmlunit.javascript.host.EventListenersContainer.executeBubblingListeners(EventListenersContainer.java:230)
    at com.gargoylesoftware.htmlunit.javascript.host.Node.fireEvent(Node.java:804)
    at com.gargoylesoftware.htmlunit.javascript.host.Node.fireEvent(Node.java:738)
    at com.gargoylesoftware.htmlunit.html.HtmlElement$1.run(HtmlElement.java:869)
    at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:602)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:507)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.fireEvent(HtmlElement.java:874)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.doClickFireClickEvent(HtmlElement.java:1311)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.click(HtmlElement.java:1253)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.click(HtmlElement.java:1205)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.dblClick(HtmlElement.java:1351)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.dblClick(HtmlElement.java:1326)
    at prototype.Profile.postLinkOnWall(Profile.java:225)
    at html.Log.findNext(Log.java:150)
    at prototype.Prtp.main(Prtp.java:49)
Caused by: net.sourceforge.htmlunit.corejs.javascript.EcmaError: ReferenceError: "Bootloader" is not defined.
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3603)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3587)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.notFoundError(ScriptRuntime.java:3657)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.nameOrFunction(ScriptRuntime.java:1749)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.name(ScriptRuntime.java:1690)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1622)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.java:798)
    at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:105)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.doTopCall(ContextFactory.java:405)
    at com.gargoylesoftware.htmlunit.javascript.HtmlUnitContextFactory.doTopCall(HtmlUnitContextFactory.java:309)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3031)
    at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:103)
    at com.gargoylesoftware.htmlunit.javascript.host.EventHandler.call(EventHandler.java:81)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$4.doRun(JavaScriptEngine.java:609)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:669)
    ... 21 more
Enclosed exception: 
net.sourceforge.htmlunit.corejs.javascript.EcmaError: ReferenceError: "Bootloader" is not defined.
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3603)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3587)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.notFoundError(ScriptRuntime.java:3657)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.nameOrFunction(ScriptRuntime.java:1749)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.name(ScriptRuntime.java:1690)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1622)
    at script.onclick(onclick event for HtmlDivision[<div class="_119 stat_elem focus_target mtm mbl _5bsm _6dh _51z6" id="u_0_k" data-location="maincolumn" onclick="Bootloader.loadComponents(&quot;ComposerXControllerBootload&quot;, emptyFunction);">] in https://www.facebook.com/?_fb_noscript=1)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.java:798)
    at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:105)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.doTopCall(ContextFactory.java:405)
    at com.gargoylesoftware.htmlunit.javascript.HtmlUnitContextFactory.doTopCall(HtmlUnitContextFactory.java:309)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3031)
    at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:103)
    at com.gargoylesoftware.htmlunit.javascript.host.EventHandler.call(EventHandler.java:81)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$4.doRun(JavaScriptEngine.java:609)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:669)
    at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:602)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:507)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.callFunction(JavaScriptEngine.java:616)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.callFunction(JavaScriptEngine.java:591)
    at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScriptFunctionIfPossible(HtmlPage.java:985)
    at com.gargoylesoftware.htmlunit.javascript.host.EventListenersContainer.executeEventHandler(EventListenersContainer.java:210)
    at com.gargoylesoftware.htmlunit.javascript.host.EventListenersContainer.executeBubblingListeners(EventListenersContainer.java:230)
    at com.gargoylesoftware.htmlunit.javascript.host.Node.fireEvent(Node.java:804)
    at com.gargoylesoftware.htmlunit.javascript.host.Node.fireEvent(Node.java:738)
    at com.gargoylesoftware.htmlunit.html.HtmlElement$1.run(HtmlElement.java:869)
    at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:602)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:507)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.fireEvent(HtmlElement.java:874)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.doClickFireClickEvent(HtmlElement.java:1311)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.click(HtmlElement.java:1253)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.click(HtmlElement.java:1205)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.dblClick(HtmlElement.java:1351)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.dblClick(HtmlElement.java:1326)
    at prototype.Profile.postLinkOnWall(Profile.java:225)
    at html.Log.findNext(Log.java:150)
    at prototype.Prtp.main(Prtp.java:49)
== CALLING JAVASCRIPT ==
function () {
    [native code, arity=0]
}

======= EXCEPTION END ========

В поле, где я пишу, действует на обычном браузере функцию переформатирования, которая не выполняется с помощью HtmlUnit, поэтому я попытался принудительно выполнить ее с помощью dbclick().

4b9b3361

Ответ 1

HtmlUnit не очень хорошо работает с JavaScript. Он часто выдает ошибки, жалующиеся на переменные или функции, которые не определены.

В этом смысле браузеры реальной жизни (FireFox, Internet Explorer, Chrome и т.д.) гораздо более гибкие. Это означает, что они позволят синтаксически неправильные фрагменты HTML и JavaScript (например: не определять функции или не заканчивать HTML-теги).

HtmlUnit ожидает, что все будет (почти) совершенным. Хотя, он исправит некоторые недостающие конечные теги HTML, в общем, он ожидает, что код на страницах не будет содержать каких-либо ошибок. Более того, даже если все выглядит правильно, HtmlUnit может даже жаловаться.

Некоторые предметы, о которых вы думаете, следующие:

  • Наиболее важным является переключение между разными BrowserVersions. Вы можете установить их при создании объекта WebClient. Internet Explorer (по иронии судьбы) показал мне лучшие результаты, когда дело доходит до интерпретации JavaScript.
  • Убедитесь, что ваш код HTML и JavaScript верны.
  • Избегайте использования сложных библиотек (jQuery, похоже, правильно поддерживается)
  • Попробуйте использовать не минимизированные версии библиотек
  • Если вы используете jQuery (или другие подобные библиотеки), избегайте сложных методов jQuery (например: динамическое добавление событий к элементам).

Конечно, эти комментарии будут применяться, если у вас есть контроль над исходным кодом, который вы получаете с сервера. Иногда это не так. В этой ситуации ваши руки еще более связаны.

Один из вариантов - исключить исключение с помощью:

webClient.getOptions().setThrowExceptionOnScriptError(false);

Хотя это приведет к вам, исключение не исправит ошибку JavaScript. Это означает, что если часть кода JS, которая выбрасывает это исключение, имеет решающее значение в вашей логике, я имею в виду, что вы абсолютно зависите от результата выполнения этого кода, тогда вы не можете позволить HtmlUnit обрабатывать ваш JS. Если это произойдет из-за запроса AJAX, вы можете самостоятельно выполнить запрос самостоятельно, вместо того чтобы позволить HtmlUnit сделать это.

С другой стороны, если JS-код, который дает вам проблемы, не является критическим в вашей логике, я имею в виду, что он может просто скрывать элемент или изменять цвет, который вам неинтересен, а затем подавлять исключение это будет путь.

Осталось немного вариантов.

Ответ 2

Попробуйте настроить веб-клиента для исключения исключений:

client.getOptions().setThrowExceptionOnScriptError(false);

Ответ 3

У меня была такая же проблема, когда я получил какой-то сайт с методом:

webClient.getPage("http://somepage.com");

Если вам не нужно использовать JavaScript для работы с веб-сайтами, вы можете написать:

webClient.getOptions().setJavaScriptEnabled(false);

В моем случае это работает хорошо, и сценарий выполняется немедленно (когда я использовал только webClient.getOptions().setThrowExceptionOnScriptError(false), сценарий всегда пытался выполнить плохой код JavaScript и в течение примерно 10 секунд выписывал сообщения об исключениях в консоли, поэтому я не рекомендую использовать его).