如何在Webview中获取所显示内容的HTML

时间:2016-09-17 13:04:53

标签: javascript android html webview jsoup

出于教育原因,我正在学习解析和报废HTML内容。 我看到了很多关于检索webview中显示的html内容的问题和答案。 我的问题是,我无法获得整个HTML,我认为它应该是什么样子。当我在Safari中检查URL时,所有项目都可以在HTML中找到,但是当我从webview加载相同URL的HTML时,会丢失项目。 我的代码现在: `

private WebView wv;

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

    wv = (WebView) findViewById(R.id.webView);
    wv.getSettings().setJavaScriptEnabled(true);

    wv.addJavascriptInterface(new LoadListener(), "HTMLOUT");
}

@Override
protected void onStart() {
    super.onStart();

    wv.setWebViewClient(new WebViewClient() {
        public void onPageFinished(WebView view, String url) {
            if(wv.getProgress() == 100) {
                view.loadUrl("javascript:window.HTMLOUT.processHTML(document.documentElement.innerHTML);");
            }
        }
    });


    wv.loadUrl("http://hdfilme.tv/movie-movies?order_f=view&order_d=desc&per_page=#");
}

class LoadListener{
    @JavascriptInterface
    public void processHTML(String html) {
        longInfo(html);
    }
}

public static void longInfo(String str) {
    if (str.length() > 4000) {
        Log.i("DEBUG", str.substring(0, 4000));
        longInfo(str.substring(4000));
    } else
        Log.i("DEBUG", str);
}`

Usuallay我使用Jsoup连接和解析HTML,但在这种情况下,网页使用CloudFlare,我无法成功加载页面HTML。

我发现现在我的代码中没有加载包含<span class="hot"></span>标记的网页的每个Listitem。

我错过了什么?

UPDATE1

F.Klein的暗示做到了!

我真的不明白为什么设置用户代理如下: wv.getSettings().setUserAgentString("Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13");

改变了检索到的HTML,就像我想象的那样。 webview中显示的内容是在设置用户代理之前和之后。

UPDATE2

我一直很高兴...更改用户代理最终会丢失要显示的项目,但现在加载之前的其他项目已经消失了???我没有遇到问题。

1 个答案:

答案 0 :(得分:1)

如前所述,该页面的移动版本似乎与默认版本不同:移动版本有50个div元素,其中找到类box-product,而默认版本找到70元件。

<强>修正

String userAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36";
wv.getSettings().setUserAgentString(userAgent);

您提到的用户代理(更新1)是移动版本的用户代理,因此与没有设置用户代理(在Android上默认为移动版本)相同的结果。

使用Rhino而不使用WebView的替代方法(计算获取访问Cookie的挑战):

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

    new BackgroundTask().execute();

}

class BackgroundTask extends AsyncTask<Void,Void,Void>{

    @Override
    protected Void doInBackground(Void... voids) {
        scrapePage();
        return null;
    }
}

private void scrapePage() {

    Map<String, String> cookies;
    final String referrer = "http://hdfilme.tv/movie-movies?order_f=view&order_d=desc&per_page=0";

    try {

        Connection.Response res = Jsoup.connect("http://hdfilme.tv/movie-movies?order_f=view&order_d=desc&per_page=#")
                .followRedirects(true).header("Connection", "keep-alive").userAgent(userAgent)
                .ignoreHttpErrors(true).header("host", "hdfilme.tv").referrer(referrer).method(Connection.Method.GET)
                .execute();

        cookies = res.cookies();

        Document doc = Jsoup.parse(res.body());

        String[] scriptlines = doc.select("script").toString().split("\n");

        StringBuilder builder = new StringBuilder();
        builder.append("var a={};");

        for (String line : scriptlines) {
            if (line.contains("var s,t,o,p,b,r,e,a,k,i,n,g")) {
                builder.append(line.trim());
                builder.append("t=\"hdfilme.tv\"");
            }
            if (line.contains("a.value = parseInt")) {
                builder.append(line.trim());
            }
        }

        int jschl_answer = runRhino(builder.toString());
        String jschl_vc = doc.select("input[name=jschl_vc]").first().attr("value");
        String pass = doc.select("input[name=pass]").first().attr("value");

        Log.e("info","Acquiring access cookies (takes about 4 seconds).");

        try {
            Thread.sleep(4000); //DDOS protection
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        String requestUrl = "http://hdfilme.tv/cdn-cgi/l/chk_jschl";

        res = Jsoup.connect(requestUrl).followRedirects(true).userAgent(userAgent)
                .header("Referer", "http://hdfilme.tv/movie-movies?order_f=view&order_d=desc&per_page=")
                .data("jschl_vc", jschl_vc).ignoreHttpErrors(true).cookies(cookies)
                .data("jschl_answer", "" + jschl_answer).data("pass", pass).header("host", "hdfilme.tv")
                .method(Connection.Method.GET).timeout(5000).execute();

        Log.e("repsonse",res.statusCode() + " - " + res.statusMessage());

        cookies.putAll(res.cookies());

        builder = new StringBuilder();
        builder.append("\tcookies");
        for (String cookie : cookies.keySet()) {
            builder.append("\n\t\t" + cookie + ":" + cookies.get(cookie));
        }

        Log.e("cookies", builder.toString());

        doc = Jsoup.connect("http://hdfilme.tv/movie-movies?order_f=view&order_d=desc&per_page=#")
                .cookies(cookies)
                .userAgent(userAgent)
                .timeout(10000).referrer(referrer).header("host", "hdfilme.tv").followRedirects(true).get();

        builder = new StringBuilder();
        builder.append("elements");

        for (Element element : doc.select(selector)) {
            builder.append("\n"+element.select("a[href]").attr("abs:href"));
        }

        Log.e("elements","total number of elements="+doc.select(selector).size()+"\n"+builder.toString());

    } catch (IOException e) {
        e.printStackTrace();
    }
}

private int runRhino(String jsSource) {
    Context rhino = Context.enter(); // org.mozilla.javascript.Context;

    // Turn off optimization to make Rhino Android compatible
    rhino.setOptimizationLevel(-1);

    Scriptable scope = rhino.initStandardObjects();
    rhino.evaluateString(scope, jsSource, "ScriptAPI", 1, null);

    NativeObject object = (NativeObject) scope.get("a", scope);
    return (int) ((Double) object.get("value") / 1);
}