Erreur E: xecuting javascript à l'aide de HtmlUnit

J'essaie d'exécuter un javascript sur l'url suivante: http://steamcommunity.com/id/bobcatchris/inventory#730 . Je peux le faire en utilisant google chrome en ouvrant la console en appuyant sur ctrl + shift + j et en collant le script suivant:

 var list = []; var size = Object.keys(g_ActiveInventory.rgInventory).size(); var counter = 0; while (counter < size) { list.push(g_ActiveInventory.rgInventory[Object.keys(g_ActiveInventory.rgInventory)[counter]].market_name); counter +=1; } 

Il retourne: 150 Ensuite, dans la ligne suivante, j'écris: >list et il renvoie un tableau de longueur 150.

Lorsque j'essaie de le faire dans HtmlUnit comme HtmlUnit :

  public static void main(String[] args) throws IOException { WebClient webClient=new WebClient(BrowserVersion.FIREFOX_17); HtmlPage page=webClient.getPage("http://steamcommunity.com/id/bobcatchris/inventory#730"); String script="var list = [];\n" + "\n" + "\n" + "var size = Object.keys(g_ActiveInventory.rgInventory).size();\n" + "\n" + "\n" + "\n" + "var counter = 0;\n" + "\n" + "while (counter < size) {\n" + " list.push(g_ActiveInventory.rgInventory[Object.keys(g_ActiveInventory.rgInventory)[counter]].market_name);\n" + " counter +=1;\n" + "}"; Object result = page.executeJavaScript(script).getJavaScriptResult(); System.out.println(result); } 

Je reçois l'exception suivante:

 Exception in thread "main" ======= EXCEPTION START ======== EcmaError: lineNumber=[4] column=[0] lineSource=[<no source>] name=[TypeError] sourceName=[injected script] message=[TypeError: Expected argument of type object, but instead had type object (injected script#4)] com.gargoylesoftware.htmlunit.ScriptException: TypeError: Expected argument of type object, but instead had type object (injected script#4) 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.execute(JavaScriptEngine.java:570) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:545) at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScriptIfPossible(HtmlPage.java:959) at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScript(HtmlPage.java:927) at Scraper.main(Scraper.java:32) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) Caused by: net.sourceforge.htmlunit.corejs.javascript.EcmaError: TypeError: Expected argument of type object, but instead had type object (injected script#4) 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.typeError(ScriptRuntime.java:3608) at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.typeError1(ScriptRuntime.java:3618) at net.sourceforge.htmlunit.corejs.javascript.ScriptableObject.ensureScriptable(ScriptableObject.java:2095) at net.sourceforge.htmlunit.corejs.javascript.NativeObject.execIdCall(NativeObject.java:287) at net.sourceforge.htmlunit.corejs.javascript.IdFunctionObject.call(IdFunctionObject.java:89) at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1531) 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.exec(InterpretedFunction.java:115) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$3.doRun(JavaScriptEngine.java:561) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:669) ... 12 more Enclosed exception: net.sourceforge.htmlunit.corejs.javascript.EcmaError: TypeError: Expected argument of type object, but instead had type object (injected script#4) 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.typeError(ScriptRuntime.java:3608) at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.typeError1(ScriptRuntime.java:3618) at net.sourceforge.htmlunit.corejs.javascript.ScriptableObject.ensureScriptable(ScriptableObject.java:2095) at net.sourceforge.htmlunit.corejs.javascript.NativeObject.execIdCall(NativeObject.java:287) at net.sourceforge.htmlunit.corejs.javascript.IdFunctionObject.call(IdFunctionObject.java:89) at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1531) at script(injected script:4) 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.exec(InterpretedFunction.java:115) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$3.doRun(JavaScriptEngine.java:561) 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.execute(JavaScriptEngine.java:570) at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:545) at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScriptIfPossible(HtmlPage.java:959) at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScript(HtmlPage.java:927) at Scraper.main(Scraper.java:32) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) ======= EXCEPTION END ======== 

L'exception de génération de ligne est:

 Object result = page.executeJavaScript(script).getJavaScriptResult(); 

Alors, comment puis-je exécuter ce script à partir de HtmlUnit comme je le fais depuis la console google chrome?

Ce sont vos erreurs de script javascript traduites à Java exceptions par votre framework.

C'est parce que vous n'avez pas défini explicitement l'option setThrowExceptionOnScriptError de votre WebClient sur false .

À moins qu'il n'y ait absolument aucune erreur dans les js , il est utile de toujours mettre cette valeur comme fausse, sauf si elle interfère avec les résultats que vous recherchez.

En règle générale, ce sont mes paramètres de webclient lorsqu'ils traitent avec js et ajax via HtmlUnit .

 final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_17, PROXY_HOST, PROXY_PORT); WebRequest request = new WebRequest(new URL( "http://steamcommunity.com/id/bobcatchris/inventory#730")); webClient.getOptions().setThrowExceptionOnScriptError(false); webClient.setJavaScriptTimeout(10000); webClient.getOptions().setJavaScriptEnabled(true); webClient.setAjaxController(new NicelyResynchronizingAjaxController()); webClient.getOptions().setTimeout(10000); HtmlPage page = webClient.getPage(request); String script="var list = [];\n" + "\n" + "\n" + "var size = Object.keys(g_ActiveInventory.rgInventory).size();\n" + "\n" + "\n" + "\n" + "var counter = 0;\n" + "\n" + "while (counter < size) {\n" + " list.push(g_ActiveInventory.rgInventory[Object.keys(g_ActiveInventory.rgInventory)[counter]].market_name);\n" + " counter +=1;\n" + "}"; Object result = page.executeJavaScript(script).getJavaScriptResult(); System.out.println(result); 

Si j'essaie votre code, avec les paramètres ci-dessus, j'ai 150.0 imprimé sur la console, ce qui, selon moi, fonctionne comme prévu.

MODIFIER:

Pour parcourir la list complète du tableau:

 String script="var list = [];\n" + "\n" + "\n" + "var size = Object.keys(g_ActiveInventory.rgInventory).size();\n" + "\n" + "\n" + "\n" + "var counter = 0;\n" + "\n" + "while (counter < size) {\n" + " list.push(g_ActiveInventory.rgInventory[Object.keys(g_ActiveInventory.rgInventory)[counter]].market_name);\n" + " counter +=1;\n" + "}" + "list"; Object result = page.executeJavaScript(script).getJavaScriptResult(); if (result instanceof NativeArray) { for (Object obj : (NativeArray)result) { System.out.println(obj); } } 

Au-dessus, j'ai changé les js pour inclure la liste comme paramètre de retour et NativeArray sur NativeArray pour obtenir chaque élément.

Sortie:

 P2000 | Scorpion (Factory New) AK-47 | Black Laminate (Field-Tested) ★ StatTrak™ Karambit | Case Hardened (Minimal Wear) CS:GO Case Key CS:GO Case Key 

Vous pouvez lire beaucoup sur leurs paramètres ajax à leurs FAQ – ici .