【问题标题】:Android - Webview HTML code extraction doesn't work (Javascript)Android - Webview HTML 代码提取不起作用(Javascript)
【发布时间】:2015-01-22 21:57:17
【问题描述】:

我正在编写一个应用程序: - 在 Web 视图中加载 URL; - 通过 javascript 代码提取 HTML; - 在 LOG 中显示提取的 HTML 代码。

由于我需要在未启用 Javascript 的情况下加载页面(以避免页面的某些行为),因此我尝试了以下代码: - 我在禁用 Javascript 的情况下在 webview 中加载页面; - 加载页面时,我启用 Javascript; - 然后,应用程序执行提取 HTML 代码所需的 Javascript。

不幸的是,在 Android 4.0.4 上以调试模式执行代码时,它会报错:

01-22 22:37:56.575: E/Web Console(7605): Uncaught TypeError: Cannot call method 'processHTML' of undefined at null:1

如果我删除 myBrowserSettings.setJavaScriptEnabled(false); 声明,在 loadurl 调用之后,一切正常。

我可以做些什么来让下面的代码工作?

package com.stefano.formfiller;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.WebSettings.PluginState;

public class MainActivity extends Activity {

    WebView myBrowser;
    String urlToBrowse = "http://www.mywebsite.com";
    String htmlCode = null;
    StringBuffer buffer = new StringBuffer();

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

          myBrowser = (WebView)findViewById(R.id.webView1);

          //Browser settings
          WebSettings myBrowserSettings = myBrowser.getSettings();

          //Prevent cache to be used
          myBrowserSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
          myBrowserSettings.setAppCacheEnabled(false);

          //General settings
          myBrowserSettings.setJavaScriptEnabled(true);
          Log.d("Stefano", "JS enabled");

          //FIREFOX user agent
          myBrowserSettings.setUserAgentString("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0");


          myBrowser.setWebChromeClient(new WebChromeClient());
          myBrowser.setWebViewClient(new WebViewClient() {
              public void onPageFinished(WebView view, String url) 
              { 

                    WebSettings myBrowserSettings = myBrowser.getSettings();
                    myBrowserSettings.setJavaScriptEnabled(true);
                    Log.d("Stefano", "JS enabled");

                    Log.d("Stefano", "OnPageFinished running"); 

              } });


          //Start the delayed HTML code extraction
          delayedStartHtmlExtractor(16000);
          Log.d("Stefano", "DelayedStart HTML Extractor launched");

          //Prepare Javascript to extract the HTML code from the webview
          myBrowser.addJavascriptInterface(new LoadListener(), "HTMLOUT");

          myBrowser.loadUrl(urlToBrowse);
          Log.d("Stefano", "Main URL requested");

          myBrowserSettings.setJavaScriptEnabled(false);
          Log.d("Stefano", "JS disabled");
    }   


    //Delayed HTML extraction
    public void delayedStartHtmlExtractor(final int delay){
        Handler handler = new Handler();

        handler.postDelayed(new Runnable() 
        {

            @Override
            public void run() 
            {                           


                myBrowser.loadUrl("javascript:window.HTMLOUT.processHTML('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');");
                Log.d("Stefano", "HTML extraction launched");

                        }
            }, delay);
    }

    //Insert the HTML code in the log information

    class LoadListener{
        public void processHTML(String html)
        {
            Log.d("Stefano", "HTML Extraction in progress...");


            Log.e("HTML CODE",html);
        }
    }

更新: 我有一个疑问:代码在启用 Javascript 时实例化 Javascript 接口(通过 myBrowser.addJavascriptInterface(new LoadListener(), "HTMLOUT"););然后,我在 URL 调用后禁用 javascript,以便在页面完全加载时重新启用 Javascript。

可能是当我使用实例化接口禁用 Javascript 时,我“切断了 Javascipt 和 Java 代码之间的通信通道”?

【问题讨论】:

  • 您的评论不完整...

标签: java javascript android jquery webview


【解决方案1】:

在接口设置后添加myBrowser.loadData(...),像这样

myBrowser.addJavascriptInterface(new LoadListener(), "HTMLOUT");
myBrowser.loadData("", "text/html", null);
myBrowser.loadUrl(urlToBrowse);

此外,由于您将在 oncreate 方法结束时禁用 js,因此无需在首次亮相时启用它 :)

希望有帮助

【讨论】:

  • 我会尽力让你知道的。你能解释一下为什么它应该起作用吗?我从未见过同时加载 loaddata 和 loadurl 的代码。谢谢,
  • 我看到,在addJavascriptInterface 的文档中,他们说添加的对象在页面下一次(重新)加载之前不会出现在 JavaScript 中。你的代码看起来合乎逻辑,但奇怪的是,它只有在我们添加第一个 loadData 时才有效!
  • 好的,这是对我有用的代码的gist,它基于您的代码
  • 感谢您的努力。我正在处理它,但如果我将“google.it/search?q=dog”加载为 URL,它会加载启用 Javascript 的页面;所以,这不是我需要的;正如我在问题中所写,我需要在未启用 Javascript 的情况下加载页面。
【解决方案2】:

当您实例化您的 LoadListener 对象时,请尝试以下操作:

this.new LoadListener();

【讨论】:

  • 我试过这个“myBrowser.addJavascriptInterface(new this.LoadListener(), "HTMLOUT");”但它会产生错误[令牌“this”上的Sintax错误,无效名称]
  • 我将上面的行改为 this.new LoadListener() 而不是 new this.LoadListener()。试一试,告诉我会发生什么!另外,LoadListener 不是静态类有什么原因吗?
  • 没有改变;同样的情况。不,没有什么特别的理由不能保持静止。我们可以试试别的吗?你在想什么?
  • 我做了一些测试;似乎 JavascriptInterface 未正确加载。你有什么想法吗?
  • 在这一行:myBrowser.loadUrl("javascript:window.HTMLOUT.processHTML... 尝试删除窗口。
【解决方案3】:

首先,您应该将正确的注释 @JavascriptInterface 附加到将通过Javascript interface 调用的方法;在你的情况下:

    //..
    @JavascriptInterface
    public void processHTML(String html) {
        Log.d("Stefano", "HTML Extraction in progress...");
        Log.e("HTML CODE",html);
    }
    //..

"请注意,在页面加载之前,注入的对象不会出现在 JavaScript 中"

我想用setJavaScriptEnabled(false) 加载页面根本不会注入任何Javascript 对象,这就是您遇到此问题的方式。

一种可能的解决方法(未经测试)可能是这样的:

  • 始终使用 setJavaScriptEnabled(true) 加载页面
  • 加载经过http://www.google.com/gwt/n的网页(将加载没有JS或Flash的页面)
  • 进行处理

【讨论】:

  • 感谢您的信息。 “@JavascriptInterface”声明不适用于目标 API 级别 14(我正在使用的那个);我读到了 API 级别 17 所需的内容。无论如何,我手动测试了“google.com/gwt/n”,但它会加载没有任何内容的 URL(也几乎是完整的 HTML 代码)。所以,这是我不能接受的方式。
猜你喜欢
  • 2018-11-09
  • 1970-01-01
  • 2015-03-24
  • 2016-04-08
  • 2011-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-06
相关资源
最近更新 更多