Domanda

Su Android, ho una WebView che visualizza una pagina.

Come faccio ad avere il sorgente della pagina senza richiedere nuovamente la pagina?

Sembra WebView dovrebbe avere una sorta di metodo getPageSource() che restituisce una stringa, ma purtroppo non è così.

Se posso abilitare JavaScript, qual è il JavaScript appropriata per mettere in questa chiamata per ottenere il contenuto?

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

Soluzione

So che questa è una risposta in ritardo, ma ho trovato questa domanda, perché ho avuto lo stesso problema. Credo di aver trovato la risposta nella questo post su lexandera. com. Il codice qui sotto è fondamentalmente un cut-e-incolla dal sito. Sembra di fare il trucco.

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

Altri suggerimenti

problema 12987 , la risposta di Blundell si blocca (almeno sul mio 2.3 VM) . Invece, ho intercettare una chiamata a console.log con un prefisso speciale:

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

Questa è una risposta basata su di jluckyiv , ma penso che sia migliore e più semplice per cambiare Javascript come segue.

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

Avete preso in considerazione il recupero il codice HTML separatamente, e poi caricarlo in una WebView?

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

Sono riuscito ad ottenere questo lavoro utilizzando il codice da @ di jluckyiv risposta, ma ho dovuto aggiungere in @JavascriptInterface annotazioni al metodo processHTML nel MyJavaScriptInterface.

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

È anche necessario annotare il metodo con @JavascriptInterface se il targetSdkVersion è> = 17 - perché c'è nuovi requisiti di sicurezza in SDK 17, vale a dire tutti i metodi JavaScript deve essere annotata con @JavascriptInterface. In caso contrario, si vedrà di errore del tipo: Uncaught TypeError: Object [object Object] non ha un metodo 'processHTML' a nulla: 1

Se si sta lavorando su KitKat e, soprattutto, è possibile utilizzare il cromo debug remoto strumenti per trovare tutte le richieste e le risposte che vanno dentro e fuori del vostro WebView e anche il codice sorgente HTML della pagina visualizzata.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top