Java: 从页面获取 Java 脚本数组元素

Java: Get JavaScript Array Elements from page

我现在可以提取单个 javascript 声明,例如:

var cars = ["Saab", "Volvo", "BMW"];

从页面解析。

我希望能够从此声明中获取数组的所有元素("Saab"、"Volvo"、"BMW")。

我应该为此使用一些 javascript 引擎,还是从我的 Java 代码中获取 javascript 变量值的最佳方法。

如果已经有能够做到这一点的东西,我不想重新发明轮子,所以我只是在寻找可以用来完成这个功能的东西的建议。

您可以遍历 'window'

中的所有值
for ( var key in window )
{
   if ( typeof window]key] == 'object' && window]key].length > 0 )
   {
      //this is the array you are looking for
   }
}

您可以使用 httpunit

从 java 访问 javascript 对象

我假设您找到了一种将 java 脚本 object/array 作为字符串或流传输到您的 Java 域的方法。您现在需要的是 JSON 解析器。

一种方法是使用 json.org 或其他库。有关 json 解析的更多信息可以在此线程中找到: How to parse JSON in Java

The [org.json][1] library is easy to use. Example code below:

import org.json.*;


JSONObject obj = new JSONObject(" .... ");
String pageName = obj.getJSONObject("pageInfo").getString("pageName");

JSONArray arr = obj.getJSONArray("posts");
for (int i = 0; i < arr.length(); i++)
{
    String post_id = arr.getJSONObject(i).getString("post_id");
    ......
} You may find extra examples from: [Parse JSON in Java][2]

Downloadable jar: http://mvnrepository.com/artifact/org.json/json

[1]: http://www.json.org/java/index.html
[2]: http://theoryapp.com/parse-json-in-java/

您可能还想查看随 Java 7 引入的 jsonb (https://jcp.org/en/jsr/detail?id=353)。您可以绑定对象模型并转换 JSON 对象进入 java 个对象,反之亦然。

使用 JDK 8 下面的代码有效:

    ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");

    String js = "var carsfromjs = [\"Saab\", \"Volvo\", \"BMW\"]";

    engine.eval(js);

    String[] cars = (String[])engine.eval("Java.to(carsfromjs, \"java.lang.String[]\")");

    for(int i=0; i<cars.length; i++){

        System.out.println(cars[i]);
    }

您可以通过 "nashorn" 找到许多访问 Javascript 代码的方法:

  1. http://winterbe.com/posts/2014/04/05/java8-nashorn-tutorial/
  2. http://www.oracle.com/technetwork/articles/java/jf14-nashorn-2126515.html
  3. http://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/

方法一:JSON解析器,如Alex的回答。

方法二:Javascript parser for Java

方法 3:正则表达式(我想出了一个奇怪的方法!)

第一个模式是var\s+([a-zA-Z0-9]+)\s+=\s+\[(.*)\]\s*;*
var + 一个或多个 space(s) + 变量名($1) + 一个或多个 space(s) + 等号 +一个或多个space(s) + 数组内容($2) + ......

第二个模式是"(.*?)",得到两个引号之间的字符串。

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JSParser {
    public String arrayName;
    private String tempValues;
    public ArrayList<String> values = new ArrayList<String>();

    public boolean parseJSArray(String arrayStr){

        String p1 = "var\s+([a-zA-Z0-9]+)\s+=\s+\[(.*)\]\s*;*";
        Pattern pattern1  = Pattern.compile(p1);
        Matcher matcher = pattern1.matcher(arrayStr);
        if(matcher.find()){
            arrayName = matcher.group(1);
            tempValues = matcher.group(2);

            Pattern getVal  = Pattern.compile("\"(.*?)\"");
            Matcher valMatcher = getVal.matcher(tempValues);
            while (valMatcher.find()) { // find next match
                String value = valMatcher.group(1);
                values.add(value);
            }
            return true;
        }else{
            return false;
        }

    }

}