كيف أحصل على محتويات صفحة الويب من عرض الويب؟

StackOverflow https://stackoverflow.com/questions/2376471

  •  24-09-2019
  •  | 
  •  

سؤال

على Android ، لدي ملف WebView هذا هو عرض صفحة.

كيف أحصل على مصدر الصفحة دون طلب الصفحة مرة أخرى؟

يبدو WebView يجب أن يكون لديك نوع من getPageSource() الطريقة التي تُرجع سلسلة ، لكن للأسف لا.

إذا قمت بتمكين JavaScript ، فما هي JavaScript المناسبة التي يجب وضعها في هذه المكالمة للحصول على المحتويات؟

webview.loadUrl("javascript:(function() { " +  
    "document.getElementsByTagName('body')[0].style.color = 'red'; " +  
    "})()");  
هل كانت مفيدة؟

المحلول

أعلم أن هذا إجابة متأخرة ، لكنني وجدت هذا السؤال لأنني واجهت نفس المشكلة. أعتقد أنني وجدت الجواب في هذا المشنور على lexandera.com. الكود أدناه هو في الأساس قطع ولصق من الموقع. يبدوا انها تكفي للخدعه.

final Context myApp = this;

/* An instance of this class will be registered as a JavaScript interface */
class MyJavaScriptInterface
{
    @JavascriptInterface
    @SuppressWarnings("unused")
    public void processHTML(String html)
    {
        // process the html as needed by the app
    }
}

final WebView browser = (WebView)findViewById(R.id.browser);
/* JavaScript must be enabled if you want it to work, obviously */
browser.getSettings().setJavaScriptEnabled(true);

/* Register a new JavaScript interface called HTMLOUT */
browser.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");

/* WebViewClient must be set BEFORE calling loadUrl! */
browser.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url)
    {
        /* This call inject JavaScript into the page which just finished loading. */
        browser.loadUrl("javascript:window.HTMLOUT.processHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");
    }
});

/* load a web page */
browser.loadUrl("http://lexandera.com/files/jsexamples/gethtml.html");

نصائح أخرى

لكل العدد 12987, ، تحطم إجابة Blundell (على الأقل على 2.3 VM). بدلاً من ذلك ، أقوم بتعبئة مكالمة إلى console.log ببادئة خاصة:

// intercept calls to console.log
web.setWebChromeClient(new WebChromeClient() {
    public boolean onConsoleMessage(ConsoleMessage cmsg)
    {
        // check secret prefix
        if (cmsg.message().startsWith("MAGIC"))
        {
            String msg = cmsg.message().substring(5); // strip off prefix

            /* process HTML */

            return true;
        }

        return false;
    }
});

// inject the JavaScript on page load
web.setWebViewClient(new WebViewClient() {
    public void onPageFinished(WebView view, String address)
    {
        // have the page spill its guts, with a secret prefix
        view.loadUrl("javascript:console.log('MAGIC'+document.getElementsByTagName('html')[0].innerHTML);");
    }
});

web.loadUrl("http://www.google.com");

هذه إجابة تستند إلى Jluckyiv's، لكنني أعتقد أنه من الأفضل وأبسط تغيير JavaScript على النحو التالي.

browser.loadUrl("javascript:HTMLOUT.processHTML(document.documentElement.outerHTML);");

هل فكرت في جلب HTML بشكل منفصل ، ثم تحميله في عرض ويب؟

String fetchContent(WebView view, String url) throws IOException {
    HttpClient httpClient = new DefaultHttpClient();
    HttpGet get = new HttpGet(url);
    HttpResponse response = httpClient.execute(get);
    StatusLine statusLine = response.getStatusLine();
    int statusCode = statusLine.getStatusCode();
    HttpEntity entity = response.getEntity();
    String html = EntityUtils.toString(entity); // assume html for simplicity
    view.loadDataWithBaseURL(url, html, "text/html", "utf-8", url); // todo: get mime, charset from entity
    if (statusCode != 200) {
        // handle fail
    }
    return html;
}

تمكنت من الحصول على هذا العمل باستخدام الكود من إجابة @jluckyiv ، لكن اضطررت إلى إضافة @javaScriptInterface إلى طريقة ProcessHTML في myjavaScriptInterface.

class MyJavaScriptInterface
{
    @SuppressWarnings("unused")
    @JavascriptInterface
    public void processHTML(String html)
    {
        // process the html as needed by the app
    }
}

تحتاج أيضًا إلى التعليق على الطريقة مع @javaScriptInterface إذا كان TargetSdKversion هو> = 17 - لأن هناك متطلبات أمان جديدة في SDK 17 ، أي يجب أن تكون جميع أساليب JavaScript مع شرح مع JavaScriptInterface. وإلا سترى خطأ مثل: Unctuction Typeerror: الكائن [كائن الكائن] ليس لديه طريقة "ProcessHtml" في NULL: 1

إذا كنت تعمل على KitKat وما فوق ، فيمكنك استخدام أدوات تصحيح الأخطاء عن بُعد Chrome للعثور على جميع الطلبات والاستجابات التي تدخل وخارج WebView وأيضًا رمز مصدر HTML الخاص بالصفحة.

https://developer.chrome.com/devtools/docs/remote-debugging

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top