我正在使用 jsoup
从网站解析 HTML。有两个选项列表是从 javascript 文件中的多维数组动态创建的。由于其动态创建的 jsoup
无法解析 html 中的结果。但是,我需要的所有数据都位于 JS 文件中。理想情况下,我希望能够定期加载文件并将数组数据从该文件保存/刷新到 Android 应用程序的本地数据库中。有问题的 JS 文件是 here显示列表的网站是 here有没有一种方法可以下载此文件的选定方面以在 Java 中对其进行操作,就像在 html 中操作 DOM 一样?
最佳答案
你可以使用 WebView with a JavascriptInterface或者你可以使用 Rhino引擎。后一种方法如下所述。
第一个download Rhino (当前版本为1.7.7.1)
将 rhino jar(例如 rhino-1.7.7.1.jar
)从 lib 文件夹复制到您的 android 项目中的 libs 文件夹。
将依赖项添加到您的 build.gradle(模块:app)文件中:
dependencies {
[other dependencies]
compile files('libs/rhino-1.7.7.1.jar')
}
以下示例 Activity 加载脚本文件、修改脚本(参见注释)并执行函数以填充数组。然后检索数组并将其作为数组存储在 java 中:
MainActivity.java
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.NativeArray;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
String[][] deptarray;
String[][] zonearray;
String[][] roomarray;
String[][] studsetarrayByCode;
String[][] studsetarrayByTitle;
String[][] staffarray;
String[][] roombydeptarray;
String[][] modulearrayByCode;
String[][] modulearrayByTitle;
String[][] progarrayByCode;
String[][] progarrayByTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new RetrieveJSFileTask().execute("http://timetables.itsligo.ie:81/js/filter.js");
}
class RetrieveJSFileTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuilder builder = new StringBuilder();
String line="";
boolean store = false;
builder.append("var deptarray;");
builder.append("var zonearray;");
while ((line = in.readLine()) != null) {
if(line.startsWith("var roomarray = ")||line.startsWith("var studsetarray =")||line.startsWith("var staffarray =")||line.startsWith("var roombydeptarray =")||line.startsWith("var modulearray =")||line.startsWith("var progarray =")){
builder.append(line);
continue;
}else if(line.contains("function PopulateFilter(strZoneOrDept, cbxFilter)")){ // populates dept and zone
store = true;
}
else if(line.contains("function FilterModulesByCode(Form) {") || line.contains("function FilterModulesByTitle(Form) {") ){ // populates module
store = true;
}
else if(line.contains("function FilterStudentSetsByCode(Form) {") || line.contains("function FilterStudentSetsByTitle(Form) {") ){ // populates studset
store = true;
}
else if(line.contains("function FilterRooms(Form) {") ){ // populates room
store = true;
}
else if(line.contains("function FilterRoomsByDept(Form) {") ){ // populates roombydept
store = true;
}
else if( line.contains("function FilterProgrammesByCode(Form) {") || line.contains("function FilterProgrammesByTitle(Form) {") ){ // populates prog
store = true;
}
else if(line.contains("function FilterStaff(Form) {") ){ // populates staff
store = true;
}
else if(line.contains("var zonearray") || line.contains("var deptarray") ){ // make zone and dept global
line = line.replace("var ", "");
}
if(store){
builder.append(line);
}
if( line.contains("zonearray.sort()") || line.contains("modulearray.sort();") || line.contains("studsetarray.sort();") || line.contains("roomarray.sort();") || line.contains(" roombydeptarray.sort();") || line.contains(" progarray.sort();") || line.contains("staffarray.sort();") ){
builder.append("return;}"); // stop function execution after population of arrays
store = false;
continue;
}
}
in.close();
return builder.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
protected void onPostExecute(String jsSource) {
if(jsSource==null) return;
Context rhino = Context.enter();
// Turn off optimization to make Rhino Android compatible
rhino.setOptimizationLevel(-1);
Scriptable scope = rhino.initStandardObjects();
ScriptableObject.putProperty(scope, "javaContext", Context.javaToJS(this, scope));
rhino.evaluateString(scope, jsSource, "ScriptAPI", 1, null);
((Function)scope.get("PopulateFilter", scope)).call(rhino, scope, scope, new Object[]{null,null});
deptarray = getArray((NativeArray)scope.get("deptarray", scope));
zonearray = getArray((NativeArray)scope.get("zonearray", scope));
((Function)scope.get("FilterModulesByCode", scope)).call(rhino, scope, scope, new Object[]{null});
modulearrayByCode = getArray((NativeArray)scope.get("modulearray", scope));
((Function)scope.get("FilterModulesByTitle", scope)).call(rhino, scope, scope, new Object[]{null});
modulearrayByTitle = getArray((NativeArray)scope.get("modulearray", scope));
((Function)scope.get("FilterStudentSetsByCode", scope)).call(rhino, scope, scope, new Object[]{null});
studsetarrayByCode = getArray((NativeArray)scope.get("studsetarray", scope));
((Function)scope.get("FilterStudentSetsByTitle", scope)).call(rhino, scope, scope, new Object[]{null});
studsetarrayByTitle = getArray((NativeArray)scope.get("studsetarray", scope));
((Function)scope.get("FilterRooms", scope)).call(rhino, scope, scope, new Object[]{null});
roomarray = getArray((NativeArray)scope.get("roomarray", scope));
((Function)scope.get("FilterRoomsByDept", scope)).call(rhino, scope, scope, new Object[]{null});
roombydeptarray = getArray((NativeArray)scope.get("roombydeptarray", scope));
((Function)scope.get("FilterProgrammesByCode", scope)).call(rhino, scope, scope, new Object[]{null});
progarrayByCode = getArray((NativeArray)scope.get("progarray", scope));
((Function)scope.get("FilterProgrammesByTitle", scope)).call(rhino, scope, scope, new Object[]{null});
progarrayByTitle = getArray((NativeArray)scope.get("progarray", scope));
((Function)scope.get("FilterStaff", scope)).call(rhino, scope, scope, new Object[]{null});
staffarray = getArray((NativeArray)scope.get("staffarray", scope));
printArray(deptarray, "deptarray");
printArray(zonearray, "zonearray");
printArray(modulearrayByCode, "modulearrayByCode");
printArray(modulearrayByTitle, "modulearrayByTitle");
printArray(studsetarrayByCode, "studsetarrayByCode");
printArray(studsetarrayByTitle, "studsetarrayByTitle");
printArray(roomarray, "roomarray");
printArray(roombydeptarray, "roombydeptarray");
printArray(progarrayByCode, "progarrayByCode");
printArray(progarrayByTitle, "progarrayByTitle");
printArray(staffarray, "staffarray");
Context.exit();
}
private void printArray(String[][] array, String tag){
String output = "";
for(int row=0;row<array.length;row++){
for(int column=0;column<array[row].length;column++){
output+=array[row][column]+"\n";
}
}
Log.e( (tag==null?"JavaArray":tag),output);
}
private String[][] getArray(NativeArray nativeArray){
String[][] javaArray = new String[nativeArray.size()][((NativeArray)nativeArray.get(0)).size()];
for (Integer row : nativeArray.getIndexIds()) {
for(int column=0;column<((NativeArray)nativeArray.get(row)).size();column++){
javaArray[row][column] = (String)((NativeArray) nativeArray.get(row)).get(column);
}
}
return javaArray;
}
}
}
关于javascript - 解析 Java 应用程序的 js 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39457275/