最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

android - Fetching Webview HTML DOM using Coroutines - Stack Overflow

programmeradmin6浏览0评论

I write this code to use it to fetch DOM of HTML page loaded in webview after fetching I want to process the DOM using DukTape Library with remote JavaScript file (to handle any future changes of the DOM structure without forcing user to update the application) the code is for Kotlin Android project:

First the Fragment Hosting Duktape Code:

val duktape = Duktape.create()
// Bind the RetrofitBridge instance to Duktape

val webView = binding.unvisibleWebview
val retrofitBridge = RetrofitBridge(webView)
duktape.set("retrofitBridge", AndroidNetworking::class.java, retrofitBridge)

try {
    // Execute JavaScript code
    val jsCode = """var result = retrofitBridge.webViewRequest(";); result; // Return the result to Kotlin"""

    val result = duktape.evaluate(jsCode)
    Log.d("ResponseHtml", result.toString())
    println(result) // Print the output
} catch (e: Exception) {
    e.printStackTrace()
} finally {
    duktape.close() // Clean up resources
}
  1. Duktape AndroidNetworking Interface:
interface AndroidNetworking {
    fun getRequest(url: String): String
    fun postRequest(url : String): String
    fun webViewRequest(url: String): String
}
  1. webViewRequest Implementation:
override fun webViewRequest(url: String): String {
    var resultHtml: String? = null
    
    WebViewClientRequest(webView, url) { html ->
        resultHtml = html
    }
    return resultHtml ?: ""
}

  1. WebViewClientRequest class:
class WebViewClientRequest(
    private val webView: WebView,
    private val url: String,
) {

    init {
        val webSettings = webView.settings
        webSettings.javaScriptEnabled = true
        webSettings.userAgentString =
            "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36"

        val cookieManager = CookieManager.getInstance()
        cookieManager.setAcceptCookie(true)
        cookieManager.setAcceptThirdPartyCookies(webView, true)

        webView.addJavascriptInterface(JsInterface(), "HTMLOUT")
        webView.webViewClient = WebClientFetchData()

        webView.loadUrl(url)
    }

    inner class WebClientFetchData : WebViewClient() {
        override fun onPageFinished(view: WebView?, url: String?) {
            super.onPageFinished(view, url)
            // Inject JavaScript to fetch the HTML content
            webView.loadUrl(
                "javascript:window.HTMLOUT.showHTML('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');"
            )
        }

        override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) {
            super.onReceivedError(view, request, error)
            println("Error loading page: $error")
        }
    }

    inner class JsInterface {
        @JavascriptInterface
        fun showHTML(html: String) {
            println(html)
        }
    }
}

What I want to implement is to not returning webViewRequest until DOM is scraped without changing webViewRequest to suspend function in order to Work with dukeTape

I tried to use runBlocking no use also I tried the following working but I can't pass data to DukTape

runBlocking {
    WebViewClientRequest(webView, url) { html ->
        resultHtml = html
    }
}

CoroutineScope(Dispatchers.Main).launch {
    WebViewClientRequest(webView, url) { html ->
        resultHtml = html
    }
}
发布评论

评论列表(0)

  1. 暂无评论