¿Cómo obtengo los contenidos de la página web desde un WebView?

En Android, tengo un WebView que muestra una página.

¿Cómo obtengo el origen de la página sin volver a solicitarla?

Parece que WebView debería tener algún tipo de método getPageSource() que devuelva una cadena, pero lamentablemente no es así.

Si habilito JavaScript, ¿cuál es el JavaScript apropiado para poner en esta llamada para obtener los contenidos?

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

Sé que esta es una respuesta tardía, pero encontré esta pregunta porque tenía el mismo problema. Creo que encontré la respuesta en esta publicación en lexandera.com. El código a continuación es básicamente un cortar y pegar del sitio. Parece hacer el truco.

 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(''+document.getElementsByTagName('html')[0].innerHTML+'');"); } }); /* load a web page */ browser.loadUrl("http://lexandera.com/files/jsexamples/gethtml.html"); 

Según el número 12987 , la respuesta de Blundell falla (al menos en mi máquina virtual 2.3). En cambio, intercepto una llamada a console.log con un prefijo especial:

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

Esta es una respuesta basada en jluckyiv , pero creo que es mejor y más simple cambiar Javascript de la siguiente manera.

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

¿Ha considerado buscar el HTML por separado y luego cargarlo en una vista web?

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

Logré hacer que esto funcionara usando el código de la respuesta de @ jluckyiv, pero tuve que agregar la anotación @JavascriptInterface al método processHTML en MyJavaScriptInterface.

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

También debe anotar el método con @JavascriptInterface si su targetSdkVersion es> = 17 – porque hay nuevos requisitos de seguridad en SDK 17, es decir, todos los métodos javascript deben anotarse con @JavascriptInterface. De lo contrario, verá un error similar a: Uncaught TypeError: Object [object Object] no tiene el método ‘processHTML’ en null: 1

Si está trabajando en kitkat y superior, puede usar las herramientas de depuración remota de Chrome para encontrar todas las solicitudes y respuestas que entran y salen de su vista web y también el código fuente html de la página vista.

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