Question

Sur Android, j'ai une WebView qui affiche une page.

Comment puis-je obtenir la source de la page sans demander à nouveau la page?

Il semble WebView devrait avoir une sorte de méthode getPageSource() qui retourne une chaîne, mais hélas il ne fonctionne pas.

Si j'activer JavaScript, ce qui est le JavaScript approprié pour mettre dans cet appel pour obtenir le contenu?

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

La solution

Je sais que c'est une réponse tardive, mais je trouve cette question parce que j'ai eu le même problème. Je pense avoir trouvé la réponse dans ce poste sur lexandera. com. Le code ci-dessous est en fait un coupe-coller à partir du site. Il semble faire l'affaire.

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

Autres conseils

Par 12987 , les accidents de réponse de Blundell (au moins sur ma machine virtuelle 2.3) . Au lieu de cela, j'intercepter un appel à console.log avec un préfixe spécial:

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

Avez-vous envisagé aller chercher le code HTML séparément, puis de le charger dans un 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;
}

Je réussi à obtenir ce travail en utilisant le code de la réponse de @ jluckyiv mais je devais ajouter une annotation de @JavascriptInterface à la méthode processHTML dans le MyJavaScriptInterface.

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

Vous devez également annoter la méthode avec @JavascriptInterface si votre targetSdkVersion est> = 17 - parce qu'il ya de nouvelles exigences en matière de sécurité dans SDK 17, à savoir toutes les javascript méthodes doivent être annotés avec @JavascriptInterface. Sinon, vous verrez comme erreur: Uncaught TypeError: Object [object Object] n'a pas de méthode 'processHTML' à null: 1

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top