rah*_*ver 3 javascript java google-chrome htmlunit
我正在尝试在以下 URL 上执行 JavaScript:http://steamcommunity.com/id/bobcatchris/inventory#730。我可以使用 google chrome 通过按 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;
}
Run Code Online (Sandbox Code Playgroud)
它返回: 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);
}
Run Code Online (Sandbox Code Playgroud)
我收到以下异常:
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 ========
Run Code Online (Sandbox Code Playgroud)
引起异常的行是:
Object result = page.executeJavaScript(script).getJavaScriptResult();
Run Code Online (Sandbox Code Playgroud)
那么我应该如何像从 google chrome 控制台一样从 HtmlUnit 执行这个脚本呢?
这些是您的框架javascript转换为的脚本错误Java exceptions。
那是因为您没有明确地将setThrowExceptionOnScriptError您的选项设置WebClient为false。
除非 中绝对没有错误js,否则始终将此值设置为 false 很有用,除非它会干扰您正在寻找的结果。
通常,这些是我webclient在处理js和ajax通过时的设置HtmlUnit。
final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_17,\n PROXY_HOST, PROXY_PORT);\n\nWebRequest request = new WebRequest(new URL(\n "http://steamcommunity.com/id/bobcatchris/inventory#730"));\n\nwebClient.getOptions().setThrowExceptionOnScriptError(false);\nwebClient.setJavaScriptTimeout(10000);\nwebClient.getOptions().setJavaScriptEnabled(true);\nwebClient.setAjaxController(new NicelyResynchronizingAjaxController());\nwebClient.getOptions().setTimeout(10000);\n\nHtmlPage page = webClient.getPage(request);\n\n String script="var list = [];\\n" +\n "\\n" +\n "\\n" +\n "var size = Object.keys(g_ActiveInventory.rgInventory).size();\\n" +\n "\\n" +\n "\\n" +\n "\\n" +\n "var counter = 0;\\n" +\n "\\n" +\n "while (counter < size) {\\n" +\n " list.push(g_ActiveInventory.rgInventory[Object.keys(g_ActiveInventory.rgInventory)[counter]].market_name);\\n" +\n " counter +=1;\\n" +\n "}";\n Object result = page.executeJavaScript(script).getJavaScriptResult();\n System.out.println(result);\nRun Code Online (Sandbox Code Playgroud)\n\n如果我尝试您的代码,使用上述设置,我会150.0打印到控制台,我认为它按预期工作。
编辑:
\n\n遍历整个数组list:
String script="var list = [];\\n" +\n "\\n" +\n "\\n" +\n "var size = Object.keys(g_ActiveInventory.rgInventory).size();\\n" +\n "\\n" +\n "\\n" +\n "\\n" +\n "var counter = 0;\\n" +\n "\\n" +\n "while (counter < size) {\\n" +\n " list.push(g_ActiveInventory.rgInventory[Object.keys(g_ActiveInventory.rgInventory)[counter]].market_name);\\n" +\n " counter +=1;\\n" +\n "}"\n + "list";\n\n Object result = page.executeJavaScript(script).getJavaScriptResult();\n if (result instanceof NativeArray) {\n for (Object obj : (NativeArray)result) {\n System.out.println(obj); \n }\n\n }\nRun Code Online (Sandbox Code Playgroud)\n\n上面,我已将js包含列表更改为返回参数并迭代NativeArray以获取每个元素。
输出:
\n\nP2000 | Scorpion (Factory New)\nAK-47 | Black Laminate (Field-Tested)\n\xe2\x98\x85 StatTrak\xe2\x84\xa2 Karambit | Case Hardened (Minimal Wear)\nCS:GO Case Key\nCS:GO Case Key\nRun Code Online (Sandbox Code Playgroud)\n\n您可以在此处的常见问题解答中阅读有关其 ajax 设置的更多内容。
\n| 归档时间: |
|
| 查看次数: |
9110 次 |
| 最近记录: |