【问题标题】:Using JSoup CSS selectors使用 JSoup CSS 选择器
【发布时间】:2013-11-25 04:32:46
【问题描述】:

我正在尝试使用JSoup 从网站上抓取一些内容。以下是我感兴趣的页面中的一些示例 HTML 内容:

<div class="sep_top shd_hdr pb2 luna">
    <div class="KonaBody" style="padding-left:0px;">
        <div class="lunatext results_content frstluna">
            <div class="luna-Ent">
                <div class="header">
                <div class="body">
                    <div class="pbk">
                        <div id="rltqns">
                    <div class="pbk">
                        <span class="pg">
                            <span id="hotword">
                                <span id="hotword">Fizz</span>
                            </span>
                        </span>
                        <div class="luna-Ent">
                        <div class="luna-Ent">
                        <div class="luna-Ent">
                        <div class="luna-Ent">
                    </div>
                    <div class="pbk">
                        <span class="sectionLabel">
                        <span class="pg">
                            <span id="hotword">
                                <span id="hotword">Buzz</span>
                            </span>
                        </span>
                        <span class="pg">
                            <span id="hotword">
                                <span id="hotword">Foo</span>
                            </span>
                        </span>
                        <span class="pg">
                            <span id="hotword">
                                <span id="hotword">Bar</span>
                            </span>
                        </span>
                    </div>
                <div class="tail">
            </div>
            <div class="rcr">
        <!-- ... rest of content omitted for brevity -->

我有兴趣获取页面中所有hotwords 的列表(如“Fizz”、“Buzz”、“Foo”和“Bar”)。 但我不能只查询hotword,因为他们到处使用hotword 类来装饰许多不同的元素。 具体来说,我需要里面存在的所有hotwords pbk pg hotword 元素。注意 pbks 可以包含 0+ pgs, pgs 可以包含 0+ hotwords, hotwords 可以包含 1+ other hotwords。我有以下代码:

// Update, per PShemo:
Document doc = Jsoup.connect("http://somesite.example.com").get();

System.out.println("Starting to crawl...");

// Get the document's .pbk elements.
Elements pbks = doc.select(".pbk");

List<String> hotwords = new ArrayList<String>();

System.out.println(String.format("Found %s pbks.", pbks.size()));
int pbkCount = 0;
for(Element pbk : pbks) {
    pbkCount++;

    // Get the .pbk element's .pg elements.
    for(Element pg : pbk.getElementsByClass("pg")) {
        System.out.println(String.format("PBK #%s has %s pgs.", pbkCount, pbk.getElementsByClass("pg").size()));
        Element hotword = pg.getElementById("hotword");

        System.out.println("Adding hotword: " + hotword.text());
        hotwords.add(hotword.text());
    }
}

运行该代码会产生以下输出:

Starting to crawl...
Found 3 pbks.

我要么没有正确使用 JSoup API,要么没有使用正确的选择器,或者两者兼而有之。关于我要去哪里出错的任何想法?提前致谢!

【问题讨论】:

    标签: java css-selectors web-crawler jsoup


    【解决方案1】:
    Elements hotwords = document.select("#hotwords");
    
    for (Element hotword : hotwords){
        String word = hotword.getText();
    }
    

    【讨论】:

    • 感谢@William Falcon,但这也不起作用。 hotword 变量的大小为 0。
    【解决方案2】:

    如果您使用getElementsByClass,则无需在其前面添加.,只需使用类名,如getElementsByClass("pg"),而不是getElementsByClass(".pg")

    getElementById 也是如此。不要在 id 值之前添加 #。只需使用getElementById("hotword")

    此外,您的 divs 与 pbk 类似乎是嵌套的,因此 getElementsByClass 可能会给您重复的结果。


    在知道您要解析的页面后,您可以使用一个选择器来解析。试试这样吧

    for (Element element:doc.select("div.body div.pbk span.pg")){
        System.out.println(element.text());
    }
    

    【讨论】:

    • 谢谢@Pschemo (+1) - 这有点帮助,但现在它告诉我文档中没有热词,我知道这是错误的。我实际上要访问的 URL 是 http://dictionary.reference.com/browse/quick?s=t,我正在尝试累积一个特定单词的所有不同“单词类型”(形容词、名词、动词)的列表。例如,在那个链接上,“quick”这个词有 3 种不同的类型:形容词、名词和副词。我怎样才能调整我的 JSoup 选择器来获得一个 List ,其中包含“形容词”、“名词”和“动词”的值?
    • @TicketMonster 我稍微更新了我的代码。它似乎可以按您的意愿工作。在看到 JSoup 从该站点获取的 HTML 代码后,我想出了这个解决方案(您可以通过 System.out.println(doc); 看到它)。
    • @TicketMonster 没问题 :)
    猜你喜欢
    • 1970-01-01
    • 2013-06-08
    • 2014-10-22
    • 1970-01-01
    • 2016-01-03
    • 1970-01-01
    • 2012-08-02
    • 1970-01-01
    • 2013-05-19
    相关资源
    最近更新 更多