webentwicklung-frage-antwort-db.com.de

Wie erhalte ich den Webseiteninhalt von einem WebView?

Unter Android habe ich ein WebView, das eine Seite anzeigt.

Wie erhalte ich die Seitenquelle, ohne die Seite erneut anzufordern?

Es scheint, dass WebView eine Art getPageSource() -Methode haben sollte, die eine Zeichenfolge zurückgibt, aber leider nicht.

Wenn ich JavaScript aktiviere, welches ist das richtige JavaScript, um den Inhalt in diesem Aufruf abzurufen?

webview.loadUrl("javascript:(function() { " +  
    "document.getElementsByTagName('body')[0].style.color = 'red'; " +  
    "})()");  
80
gregm

Ich weiß, dass dies eine späte Antwort ist, aber ich habe diese Frage gefunden, weil ich das gleiche Problem hatte. Ich glaube, ich habe die Antwort in diesem Beitrag auf lexandera.com gefunden. Der folgende Code ist im Grunde ein Ausschneiden und Einfügen von der Website. Es scheint den Trick zu tun.

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");
148
jluckyiv

Per Problem 12987 stürzt Blundells Antwort ab (zumindest auf meiner 2.3-VM). Stattdessen fange ich einen Aufruf von console.log mit einem speziellen Präfix ab:

// 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");
32
durka42

Dies ist eine Antwort basierend auf jluckyivs , aber ich denke, es ist besser und einfacher, Javascript wie folgt zu ändern.

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

Haben Sie darüber nachgedacht, den HTML-Code separat abzurufen und dann in eine Webansicht zu laden?

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;
}
6
larham1

Ich habe es geschafft, dies mit dem Code aus @ jluckyivs Antwort zum Laufen zu bringen, aber ich musste der processHTML-Methode in MyJavaScriptInterface die Annotation @JavascriptInterface hinzufügen.

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

Sie müssen die Methode auch mit @JavascriptInterface annotieren, wenn Ihre targetSdkVersion> = 17 ist - da SDK 17 neue Sicherheitsanforderungen enthält, d. H. Alle JavaScript-Methoden müssen mit @JavascriptInterface annotiert werden. Andernfalls wird folgender Fehler angezeigt: Uncaught TypeError: Object [object Object] hat keine Methode 'processHTML' mit dem Wert null: 1

1
javauser71

Wenn Sie an KitKat und höher arbeiten, können Sie mit den chrome remote debugging tools alle Anfragen und Antworten finden, die in Ihrer Webansicht ein- und ausgehen, sowie den HTML-Quellcode der Seite angesehen.

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

0
onusopus