Jsoup选择器返回所有值而不是搜索值

时间:2014-12-04 20:56:15

标签: java css-selectors jsoup

我正在学习如何使用jsoup并且我创建了一个名为search的方法,它使用jsoup的选择器containscontainsOwn来搜索给定的项目并返回它的价格。 (目前,项目名称是硬编码用于测试目的,但该方法稍后将接受参数以接受任何项目名称)。

我遇到的问题是选择器不起作用并且页面上的所有价格都被返回而不是被搜索的一个项目,在这种情况下是“百叶窗”。因此,在此示例中,如果您按照链接,该页面上只有一个项目显示百叶窗,价格列为“$ 30 - $ 110原始$ 18 - $ 66 sale”,但该页面上的每个项目都会被返回。

我知道使用jsoup我可以显式调用div的名称,只需从中提取信息。但是我想把它变成一个更大的项目,并从沃尔玛,西尔斯,梅西百货等其他连锁店的同一项目中提取价格。不仅仅是我在我的代码中使用的那个特定网站。所以我不能明确地调用div名称,如果我想这样做,因为这只会解决一个站点的问题,而不是其他站点的问题,我想采取一次性包含大多数这些站点的方法。

如何提取与其合法项目相关的价格?有没有办法让项目和价格提取适用于大多数网站?

我将不胜感激。

private static String search(){
    Document doc;
    String priceText = null;

    try{
        doc = Jsoup.connect("http://www.jcpenney.com/for-the-home/sale/cat.jump?id=cat100590341&deptId=dept20000011").get();
        Elements divs = doc.select("div");
        HashMap items = new HashMap();
        for(Element element : doc.select("div:contains(blinds)")){

            //For those items that say "buy 1 get 1 free"
            String buyOneText = divs.select(":containsOwn(buy 1)").text();
            Element all = divs.select(":containsOwn($)").first();
            priceText = element.select(":containsOwn($)").text();
            items.put(element, priceText);
        }
        System.out.println(priceText);
    }catch(Exception e){
        e.printStackTrace();
    }
    return priceText;
}

1 个答案:

答案 0 :(得分:0)

如果你已经尝试过至少调试你的应用程序,那么肯定的是,你会发现你的错误在哪里。 例如,在这一行放置断点:

String buyOneText = divs.select(":containsOwn(buy 1)").text();

然后你会看到,循环中的这个元素真的包含百叶窗文本。 (以及所有选择的那些)

我不知道为什么要制作超级通用工具,它们将在任何地方工作 - IMO是不可能的,并且每个页面都必须制作自己的爬虫。在这种情况下,您的代码可能看起来像这样(我必须添加超时+此代码不能完全在我身边,因为我有默认货币PLN):

private static String search() {
        Document doc;
        String priceText = null;
        try {
            doc = Jsoup.connect("http://www.jcpenney.com/for-the-home/sale/cat.jump?id=cat100590341&deptId=dept20000011").timeout(10000).get();
            Elements divs = doc.select("div[class=price_description]");
            HashMap items = new HashMap();
            for (Element element : divs.select("div:contains(blinds)")) {

                //For those items that say "buy 1 get 1 free"
                String buyOneText = divs.select(":containsOwn(buy 1)").text();
                Element all = divs.select(":containsOwn($)").first();
                priceText = element.select(":containsOwn($)").text();
                items.put(element, priceText);
            }
            System.out.println(priceText);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return priceText;
    }