Pregunta

En Android, tengo una WebView que está mostrando una página.

¿Cómo consigo la fuente de la página sin solicitar de nuevo la página?

Parece WebView debe tener algún tipo de método getPageSource() que devuelve una cadena, pero por desgracia no es así.

Si habilito JavaScript, lo que es el código JavaScript apropiada para poner en esta convocatoria para obtener el contenido?

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

Solución

Yo sé que esto es una respuesta tardía, pero me encontré con esta pregunta porque tenía el mismo problema. Creo que he encontrado la respuesta en este post en lexandera. com. El código siguiente es básicamente un cortar y pegar desde el sitio. Parece que 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");

Otros consejos

tema 12987 , la respuesta de Blundell bloquea (al menos en mi máquina virtual 2.3) . En su lugar, interceptar 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 de jluckyiv , pero creo que es mejor y más fácil de cambiar Javascript como sigue.

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

¿Ha pensado en ir a buscar el código 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;
}

He conseguido este trabajo utilizando el código de respuesta de @ jluckyiv pero tenía que añadir en la anotación @JavascriptInterface al método processHTML en el MyJavaScriptInterface.

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

También es necesario anotar el método con @JavascriptInterface si su targetSdkVersion es> = 17 - porque hay nuevos requisitos de seguridad en SDK de 17, es decir, todos los métodos JavaScript debe ser anotado con @JavascriptInterface. De lo contrario, verá error como: no detectada TypeError: Object [object Object] tiene ningún método 'processHTML' en nulo: 1

Si usted está trabajando en KitKat y por encima, se puede utilizar el cromo depuración remota herramientas para encontrar todas las peticiones y las 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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top