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

如何捕获WebView加载的HTML中特定div节点的内容?

捕获WebView中特定Div的内容截图

要实现只截取WebView中指定Div的内容,核心思路是先通过JavaScript获取目标Div在页面中的位置和尺寸,再对整页截图进行裁剪,具体步骤如下:

1. 启用JavaScript并获取Div的位置与尺寸

首先确保WebView开启JS支持,然后在页面加载完成后,注入JS代码获取目标Div的坐标和大小:

// 初始化WebView时启用JS
webView.settings.javaScriptEnabled = true

// 存储目标Div的位置与尺寸参数
var divTop = 0
var divLeft = 0
var divWidth = 0
var divHeight = 0

webView.webViewClient = object : WebViewClient() {
    override fun onPageFinished(view: WebView?, url: String?) {
        super.onPageFinished(view, url)
        // 替换成你的目标Div选择器(比如id、class)
        val targetSelector = "document.getElementById('targetDiv')" 
        webView.evaluateJavascript(
            """
            var div = $targetSelector;
            if(div) {
                var rect = div.getBoundingClientRect();
                var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
                var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
                // 适配屏幕像素密度,避免裁剪偏移
                var scale = window.devicePixelRatio;
                JSON.stringify({
                    top: Math.round((rect.top + scrollTop) * scale),
                    left: Math.round((rect.left + scrollLeft) * scale),
                    width: Math.round(rect.width * scale),
                    height: Math.round(rect.height * scale)
                })
            } else {
                null
            }
            """.trimIndent()
        ) { result ->
            if (result != "null") {
                try {
                    val jsonObject = JSONObject(result)
                    divTop = jsonObject.getInt("top")
                    divLeft = jsonObject.getInt("left")
                    divWidth = jsonObject.getInt("width")
                    divHeight = jsonObject.getInt("height")
                } catch (e: JSONException) {
                    e.printStackTrace()
                }
            }
        }
    }
}

说明:

  • 将targetDiv替换为你要截取的Div的实际ID,若用class选择器则改为document.querySelector('.your-class-name')
  • 加入devicePixelRatio是为了适配不同屏幕的像素密度,保证裁剪区域精准

2. 裁剪整页截图得到目标Div区域

基于你现有的整页截图逻辑,对获取到的Bitmap进行裁剪,只保留目标Div的区域:

screenButton.setOnClickListener {
    // 校验Div参数是否有效
    if (divWidth <= 0 || divHeight <= 0) {
        Toast.makeText(this, "未找到目标Div", Toast.LENGTH_SHORT).show()
        return@setOnClickListener
    }

    val baos = ByteArrayOutputStream()
    val randomID = Random().nextInt()
    // 获取整页截图
    val fullPageBitmap = getBitmapFromView(scrollView, scrollView.getChildAt(0).height, scrollView.getChildAt(0).width)
    
    // 处理裁剪边界,避免超出Bitmap范围
    val cropLeft = divLeft.coerceAtLeast(0)
    val cropTop = divTop.coerceAtLeast(0)
    val cropWidth = divWidth.coerceAtMost(fullPageBitmap.width - cropLeft)
    val cropHeight = divHeight.coerceAtMost(fullPageBitmap.height - cropTop)

    if (cropWidth <= 0 || cropHeight <= 0) {
        Toast.makeText(this, "裁剪区域无效", Toast.LENGTH_SHORT).show()
        fullPageBitmap.recycle()
        return@setOnClickListener
    }

    // 裁剪出目标Div的Bitmap
    val targetBitmap = Bitmap.createBitmap(fullPageBitmap, cropLeft, cropTop, cropWidth, cropHeight)
    fullPageBitmap.recycle() // 释放整页截图内存

    // 保存裁剪后的图片(原有逻辑不变,替换为targetBitmap)
    val externalStoragePublicDirectory =
        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
    val imageFile = File(externalStoragePublicDirectory, "Screenshot$randomID.png")
    FileOutputStream(imageFile).use {
        targetBitmap.compress(Bitmap.CompressFormat.PNG, 70, it)
    }
   
    // Base64编码逻辑
    targetBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos)
    val imageBytes: ByteArray = baos.toByteArray()
    val imageString: String = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        Base64.getEncoder().encodeToString(imageBytes)
    } else {
        android.util.Base64.encodeToString(imageBytes, android.util.Base64.DEFAULT)
    }
    println("Base64 Encoding : $imageString")
    
    targetBitmap.recycle() // 释放裁剪后的Bitmap内存
}

// 你的getBitmapFromView函数(确保能正确获取整页截图)
private fun getBitmapFromView(view: View, height: Int, width: Int): Bitmap {
    val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(bitmap)
    val bgDrawable = view.background
    if (bgDrawable != null) {
        bgDrawable.draw(canvas)
    } else {
        canvas.drawColor(Color.WHITE)
    }
    view.draw(canvas)
    return bitmap
}

关键注意事项

  • 若目标Div是动态生成的(比如通过AJAX加载),需等待DOM完全渲染后再执行JS获取参数,可改用window.onload或MutationObserver监听
  • 注意内存回收:及时调用recycle()释放不再使用的Bitmap,避免内存溢出
  • 若WebView设置了缩放,需确保JS获取的坐标与Bitmap的像素比例一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:40:46