web-dev-qa-db-ja.com

HTMLUnit ScriptExceptionを克服する方法?

おそらくいくつかのjs関数をトリガーするコード行で問題が発生し、例外が発生します。これを修正するにはどうすればよいですか?

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()で強制的に実行しようとしました。

21
user3054975

HtmlUnitはJavaScriptではうまく機能しません。定義されていない変数や関数についてのエラーが頻繁にスローされます。

その意味で、実生活ブラウザ(FireFox、Internet Explorer、Chromeなど)はより柔軟です。つまり、それらは構文的に正しくないHTMLおよびJavaScriptの一部を許可します(例:関数を定義しない、またはHTMLタグを終了しない)。

HtmlUnitは、すべてが(ほぼ)完璧であることを期待しています。欠落している終了HTMLタグの一部は修正されますが、一般的には、ページ内のコードになんらかのエラーが含まれないことが期待されます。さらに、すべてが正しいように見えても、HtmlUnitは文句を言うかもしれません。

あなたが考えるべきいくつかの項目は次のとおりです:

  • 最も重要なのは、異なるBrowserVersionsを切り替えることです。 WebClientオブジェクトの作成時に設定できます。 JavaScriptの解釈に関しては、Internet Explorer(皮肉なことに)が最高の結果をもたらすことが証明されています
  • HTMLとJavaScriptコードの両方が正しいことを確認してください
  • complexライブラリの使用を避けます(jQueryは適切にサポートされているようです)
  • 最小化されていないバージョンのライブラリを使用してみてください
  • たまたまjQuery(または他の同様のライブラリ)を使用している場合は、複雑なjQueryメソッド(例:要素への動的なイベントの追加)を避けてください。

もちろん、これらのコメントは、サーバーからフェッチするソースコードを制御できる場合に適用されます。時々、これはそうではありません。この状況では、あなたの手はさらに縛られます。

1つのオプションは、次のようにして例外を抑制することです。

webClient.getOptions().setThrowExceptionOnScriptError(false);

ただし、これにより例外が発生し、JavaScriptエラーは修正されません。つまり、この例外をスローしているJSコードがロジックで非常に重要である場合、つまり、そのコードの実行結果に完全に依存している場合、HtmlUnitにJSを処理させることはできません。これがAJAXリクエストの結果である場合は、HtmlUnitに任せる代わりに、手動でリクエストを発行できます。

一方、問題を引き起こしているJSコードがロジックで重要でない場合は、つまり、要素を非表示にするか、気にしない色を変更するだけで、例外を抑制することができます。行く方法。

残っているオプションは多くありません。

37
Mosty Mostacho

例外をスローしないようにWebクライアントを設定してみてください。

client.getOptions().setThrowExceptionOnScriptError(false);
10
Gokul Nath KP

私が方法でいくつかのウェブサイトを取得するとき、私はこれと同じ問題を抱えていました:

_webClient.getPage("http://somepage.com");
_

JavaScriptを使用してWebサイトを操作する必要がない場合は、次のように記述できます。

_webClient.getOptions().setJavaScriptEnabled(false);
_

私の場合、それはうまく機能し、スクリプトはすぐに実行されます(私がwebClient.getOptions().setThrowExceptionOnScriptError(false)のみを使用した場合)、スクリプトは常に不正なJavaScriptコードを実行しようとし、約10秒間コンソールに例外メッセージを書き込んだので、私はしませんそれを使用することをお勧めします)。

1
Oxygenium