You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java中通过WebView从指定类名的DOM元素获取数据

Android WebView:通过类名获取DOM元素并传递到Java层

前置准备

首先确保WebView开启JavaScript支持,并配置JS与Java的交互通道:

// 初始化WebView时的基础配置
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);

// 注入自定义Java接口供JS调用,"$$"是JS中调用的对象名
webView.addJavascriptInterface(new JsBridge(), "$$");

自定义JsBridge类,提供接收JS数据的方法(API 17+必须添加@JavascriptInterface注解):

public class JsBridge {
    @JavascriptInterface
    public void sendElementData(String elementJson) {
        // 解析并处理从JS传递的DOM元素数据
        try {
            JSONArray elements = new JSONArray(elementJson);
            for (int i = 0; i < elements.length(); i++) {
                JSONObject elem = elements.getJSONObject(i);
                String text = elem.getString("text");
                String html = elem.getString("html");
                Log.d("WebView", "元素[" + i + "] 文本:" + text + ",HTML片段:" + html);
            }
        } catch (JSONException e) {
            Log.e("WebView", "DOM数据解析失败:" + e.getMessage());
        }
    }

    // 保留原示例中的log方法(若业务需要)
    @JavascriptInterface
    public void log(String responseText, String url, String args) {
        // 原逻辑实现
    }
}

在onPageFinished中注入JS获取目标类名元素

在你提供的onPageFinished方法中,添加获取指定类名DOM元素的JS逻辑,提取数据后调用Java接口传递:

@Override
public void onPageFinished(WebView view, String url) {
    setTitle(view.getTitle());

    // 保留原有的注入代码
    view.loadUrl("javascript:function injek3(){window.hasdir=1;window.dir=function(n){var r=[];for(var t in n)'function'==typeof n[t]&&r.push(t);return r}};if(window.hasdir!=1){injek3();}");
    view.loadUrl("javascript:function injek2(){window.touchblock=0,window.dummy1=1,document.addEventListener('click',function(n){if(1==window.touchblock){n.preventDefault();n.stopPropagation();var t=document.elementFromPoint(n.clientX,n.clientY);window.ganti=function(n){t.outerHTML=n},window.gantiparent=function(n){t.parentElement.outerHTML=n},$$.print(t.parentElement.outerHTML, t.outerHTML)}},!0)}1!=window.dummy1&&injek2();");
    view.loadUrl("javascript:function injek(){window.hasovrde=1;var e=XMLHttpRequest.prototype.open;XMLHttpRequest.prototype.open=function(ee,nn,aa){this.addEventListener('load',function(){$$.log(this.responseText, nn, JSON.stringify(arguments))}),e.apply(this,arguments)}};if(window.hasovrde!=1){injek();}");

    // 新增:获取指定类名的DOM元素并传递到Java层
    String targetClass = "your-target-class"; // 替换为实际要查找的类名
    view.loadUrl("javascript:(function(){" +
        "var elems = document.getElementsByClassName('" + targetClass + "');" +
        "var data = [];" +
        "for(var i=0; i<elems.length; i++){" +
            "var elem = elems[i];" +
            // 按需提取数据,比如文本、HTML、属性等
            "data.push({" +
                "text: elem.textContent.trim()," +
                "html: elem.outerHTML," +
                "className: elem.className" +
            "});" +
        "}" +
        // 调用Java接口,转成JSON字符串便于解析
        "$$.sendElementData(JSON.stringify(data));" +
    "})()");

    super.onPageFinished(view, url);
}

更安全的替代方案(API 19+)

如果应用目标API为19及以上,推荐使用evaluateJavascript替代loadUrl,无需注入Java接口,安全性更高:

@Override
public void onPageFinished(WebView view, String url) {
    // ... 保留原有逻辑 ...

    String targetClass = "your-target-class";
    view.evaluateJavascript("(function(){" +
        "var elems = document.getElementsByClassName('" + targetClass + "');" +
        "var data = [];" +
        "for(var i=0; i<elems.length; i++){" +
            "data.push({text: elems[i].textContent.trim(), html: elems[i].outerHTML});" +
        "}" +
        "return JSON.stringify(data);" +
    "})()", new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String result) {
            if (result != null) {
                try {
                    JSONArray elements = new JSONArray(result);
                    // 解析处理数据,逻辑同JsBridge中的方法
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
    });

    super.onPageFinished(view, url);
}

关键注意点

  • DOM加载时机:onPageFinished是执行DOM操作的合适时机,但如果页面存在动态加载内容,可能需要添加延迟或监听DOM变化事件。
  • 元素匹配:若仅需第一个匹配元素,可使用document.querySelector('.target-class')替代getElementsByClassName。
  • 安全风险:避免在addJavascriptInterface的方法中暴露敏感操作,高版本系统优先使用evaluateJavascript。

内容的提问来源于stack exchange,提问作者sanju

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 05:15:30