En Android, tengo un WebView
que muestra una página.
¿Cómo obtengo la fuente de la página sin volver a solicitarla?
Parece que WebView
debería tener algún tipo de getPageSource()
método que devuelva una cadena, pero lamentablemente no lo hace.
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'; " +
"})()");
android
android-webview
Gregm
fuente
fuente
Respuestas:
Sé que esta es una respuesta tardía, pero encontré esta pregunta porque tuve el mismo problema. Creo que encontré la respuesta en esta publicación en lexandera.com. El siguiente código es básicamente un proceso de 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('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');"); } }); /* load a web page */ browser.loadUrl("http://lexandera.com/files/jsexamples/gethtml.html");
fuente
onPageFinished()
se ejecutara.browser.loadUrl
enonPageFinished
causaráonPageFinished
a ser llamado de nuevo. Es posible que desee comprobar si es la primera llamadaonPageFinished
o no antes de llamarbrowser.loadUrl
.String html = new Scanner(new DefaultHttpClient().execute(new HttpGet("www.the url")).getEntity().getContent(), "UTF-8").useDelimiter("\\A").next();
(abreviado para que quepa en un comentario :-))Según el número 12987 , la respuesta de Blundell falla (al menos en mi 2.3 VM). 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");
fuente
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);");
fuente
¿Ha considerado obtener 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; }
fuente
Logré 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 } }
fuente
También debe anotar el método con @JavascriptInterface si su targetSdkVersion es> = 17, porque hay nuevos requisitos de seguridad en el SDK 17, es decir, todos los métodos de JavaScript deben anotarse con @JavascriptInterface. De lo contrario, verá un error como: Uncaught TypeError: Object [object Object] no tiene el método 'processHTML' en nulo: 1
fuente
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
fuente