当前位置: 首页 > 面试题库 >

使用HtmlUnit错误执行JavaScript

阮阳曦
2023-03-14
问题内容

我正在尝试在以下URL上执行JavaScript
http://steamcommunity.com/id/bobcatchris/inventory#730。我可以使用谷歌浏览器通过按ctrl +
shift + j并粘贴以下脚本来打开控制台:

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;
}

它返回:150然后在下一行中,我写:>list 并且它返回长度为150的数组。

当我尝试这样做时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);
    }

我收到以下异常:

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 ========

导致异常的行是:

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

那么,我应该如何从HtmlUnit执行此脚本,就像在Google Chrome控制台中一样?


问题答案:

这些是您的框架所javascript翻译的脚本错误Java exceptions

这是因为您尚未将的setThrowExceptionOnScriptError选项显式设置WebClientfalse

除非中绝对没有错误js,否则始终将其设置为false很有用,除非它会干扰您要查找的结果。

通常,这些是我的webclient设置有问题时jsajax通过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);

如果我尝试使用您的代码,则使用上述设置,我会150.0打印到控制台上,并认为该控制台可以正常工作。

编辑:

要遍历整个数组list

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);    
                }

            }

上面,我更改了js将列表包括在内作为返回参数,并进行迭代NativeArray以获取每个元素。

输出:

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

您可以在其常见问题解答-
这里阅读有关其Ajax设置的更多信息。



 类似资料:
  • 问题内容: 我一直在使用HTMLUnit。非常适合我的要求。但这似乎非常缓慢。例如:我已经使用HTMLUnit自动化了以下场景 代码: 它运作良好100%。但是需要3分41秒 我想执行缓慢的原因是要验证页面上的每个元素。 我的问题是如何减少HTMLUnit的执行时间?有什么方法可以禁用网页上的验证。 提前致谢! 问题答案: 对于当前的htmlUnit 2.13,设置选项与maxmax提供的设置略有

  • 问题内容: 我目前正在使用HtmlUnit开发一些测试。它正在加载一个包含braintree.js(其表单加密库)的页面。我跑了一堆,但我被困在所谓的加密货币上。有问题的JS是: HtmlUnit抛出: 我想HtmlUnit不包含加密。我自己可以包括一个密码库吗? 问题答案: 根据您的评论,我不得不告诉您HtmlUnit在涉及JavaScript时令人不安。它将抱怨很多关于变量未定义和未知函数等问

  • 我正在尝试执行Spring引导;使用mvn spring-boot:run可以很好地工作。但是当我尝试将它打包为jar(我将依赖项移到lib,将二进制移到bin,将资源移到resources文件夹)命令是java-cp lib/;bin/;resource/*com.sample.sampleboot(sampleboot的jar在bin中可用)这会启动并打印main中提到的行,但是当调用appl

  • 使用命令获取此错误: jar是用mvn clean包和mvn安装构建的 聚甲醛