HtmlUnit:使用相同的WebClient

时间:2016-11-24 09:18:17

标签: java jsoup webclient htmlunit

我正在尝试使用HtmlUnit和Jsoup解析一个网站,我正面临着这个问题。 我有不同的页面要解析,我将这些页面的链接存储在一个字符串数组中。 我想循环数组的长度并解析每一页,然后以这种方式继续。

1)循环链接数组的长度 2)打开新的webclient 3)使用getPage方法从链接创建新的HtmlPage 4)解析并获得一些元素 5)关闭webclient 6)回到2)。

通过这种方式,我可以获得我想要的东西,但编码速度有点慢。所以我试图在for循环之外打开和关闭webClient。像这样:

1)打开新的webclient 2)循环链接数组的长度 3)使用getPage方法从链接创建新的HtmlPage 4)解析并获得一些元素 5)回到2)。 6)关闭webclient

速度要快得多,但我没有获得与以前相同的结果。

以这种方式使用webclient构造函数是错误的吗?

修改 遵循代码I' m测试:

    public static void main(String[] args) throws FailingHttpStatusCodeException, MalformedURLException, IOException {
        // TODO Auto-generated method stub
        java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(java.util.logging.Level.OFF);

        String[] links = {"http://www.oddsportal.com/tennis/china/atp-beijing/murray-andy-dimitrov-grigor-fTdGYm3q/#cs;2;6",
                            "http://www.oddsportal.com/tennis/china/atp-beijing/murray-andy-dimitrov-grigor-fTdGYm3q/#cs;2;9"};

        String bm = null;
        String[] odds = new String[2]; 

        //Second way
        WebClient webClient = new WebClient(BrowserVersion.CHROME);
        System.out.println("Client opened");
        for (int i=0; i<links.length; i++) {

            HtmlPage page = webClient.getPage(links[i]);
            System.out.println("Page loaded");
            Document csDoc = Jsoup.parse(page.asXml());
            System.out.println("Page parsed");

            Element table = csDoc.select("table.table-main.detail-odds.sortable").first();
            Elements cols = table.select("td:eq(0)");

            if (cols.first().text().trim().contains("bet365.it")) {
                bm = cols.first().text().trim();
                odds[i]=table.select("tbody > tr.lo").select("td.right.odds").first().text().trim();
            }
            else {
                Elements footTable = csDoc.select("table.table-main.detail-odds.sortable");
                Elements footRow = footTable.select("tfoot > tr.aver");
                odds[i] = footRow.select("td.right").text().trim();

                bm = "AVG";
            }
            webClient.close();  
        }

        System.out.println(bm +"\t" +odds[0] + "\t" + odds[1]);

}

如果我运行此代码,结果是正确的。如果我移动webClient.close();在for循环结果之外是不正确的。特别是赔率[0]等于赔率[1];

1 个答案:

答案 0 :(得分:2)

将WebClient视为浏览器的替代品。创建新的WebClient就像启动一个新的浏览器。 如果您喜欢在浏览器中执行相同的操作,则可以使用WebClient#openWindow(..)。从记忆的角度来看,如果你完成了,关闭窗口是一个好主意。

如果您正在寻找性能,为什么要重新解析整个页面Jsoup。 HtmlUnit检索页面,解析页面,创建整个DOM并在您从getPage调用返回页面之前在此dom之上运行javascript。 然后你使用HtmlUnit将Dom树序列化回Html并使用Jsoup再次解析页面。 HtmlUnit提供了许多搜索页面元素的方法。我建议您直接在自己的网页上使用此API。