当前位置: 首页 > 知识库问答 >
问题:

h2之后的第二个div

江华容
2023-03-14

我有以下超文本标记语言:

<html>
<body>

...

<h2> Blah Blah 1</h2>
<p>blah blah</p>
<div>
    <div>
        <table>
            <tbody>
                <tr><th>Col 1 Header</th><th>Col 2 Header</th></tr>
                <tr><td>Line 1.1 Value</td><td>Line 2.1 Header</td></tr>
                <tr><td>Line 2.1 Value</td><td>Line 2.2 Value</td></tr>
            </tbody>
        </table>
    </div>
</div>
<div>
    <div>
        <table>
            <tbody>
                <tr><th>Col 1 Header T2</th><th>Col 2 Header T2</th></tr>
                <tr><td>Line 1.1 Value T2</td><td>Line 2.1 Header T2</td></tr>
                <tr><td>Line 2.1 Value T2</td><td>Line 2.2 Value T2</td></tr>
                </tbody>
        </table>
    </div>
</div>

<h2> Blah Blah 2</h2>

<div>
    <div>
        <table>
            <tbody>
                <tr><th>XCol 1 Header</th><th>XCol 2 Header</th></tr>
                <tr><td>XLine 1.1 Value</td><td>XLine 2.1 Header</td></tr>
                <tr><td>XLine 2.1 Value</td><td>XLine 2.2 Value</td></tr>
            </tbody>
        </table>
    </div>
</div>
<p>blah blah</p>
<div>
    <div>
        <table>
            <tbody>
                <tr><th>XCol 1 Header T2</th><th>XCol 2 Header T2</th></tr>
                <tr><td>XLine 1.1 Value T2</td><td>XLine 2.1 Header T2</td></tr>
                <tr><td>XLine 2.1 Value T2</td><td>XLine 2.2 Value T2</td></tr>
                </tbody>
        </table>
    </div>
</div>

</body>
</html>

我想提取包含给定文本的h2标记后面的第二个DIV。

正如您可能注意到的,在第一个和第二个div中,p标签不在同一位置。

要在第一个h2之后提取DIV,以下公式将起作用:

h2:contains(Blah 1) + p + div +div

但是要提取第二个,用“布拉2”替换“布拉1”将不起作用,因为“p”标签位于其他地方,所以静态选择器将是:

h2:contains(Blah 2) + div + p +div

我需要的是一个单一的选择器公式,在这个公式中,无论p块在哪里,改变文本都会使它工作

我试过几种方法:比如。。。类型的选择器n也不起作用,因为我只知道DIV的位置wrt的h2不是DIV的父亲,而是前面的兄弟姐妹。。。

请帮忙

共有2个答案

越麒
2023-03-14

一种简单的方法是使用逗号()查询运算符,它在选择器之间执行OR。因此,您可以将P标记所在位置的两种变体组合起来。

h2:contains(Blah 2) + div ~ div, h2:contains(Blah 2) ~ div + div

这里有一个例子。学校操场。

马华茂
2023-03-14

我有两个想法如何实现这一点。
第一个是删除每个

    public void execute1(String html) {
        Document doc = Jsoup.parse(html);
        // first approach: remove every <p> to simplify document
        Elements paragraphs = doc.select("p");
        for (Element paragraph : paragraphs) {
            paragraph.remove();
        }
        // then one selector will return what you want in both cases
        System.out.println(selectSecondDivAfterH2WithText(doc, "Blah 1"));
        System.out.println(selectSecondDivAfterH2WithText(doc, "Blah 2"));
    }

    private Element selectSecondDivAfterH2WithText(Document doc, String text) {
        return doc.select("h2:contains(" + text + ")+div+div").first();
    }

第二种方法是迭代“h2:contains(“text”)”和“手动”查找第二个

    public void execute2(String html) {
        Document doc = Jsoup.parse(html);
        System.out.println(selectSecondDivAfterH2WithText2(doc, "Blah 1"));
        System.out.println(selectSecondDivAfterH2WithText2(doc, "Blah 2"));
    }

    private Element selectSecondDivAfterH2WithText2(Document doc, String text) {
        int counter = 2;
        // find h2 with given text
        Element h2 = doc.select("h2:contains(" + text + ")").first();
        // select every sibling after this h2 element
        Elements siblings = h2.nextElementSiblings();
        // loop over them
        for (Element sibling : siblings) {
            // skip everything that's not a div
            if (sibling.tagName().equals("div")) {
                // count how many divs left to skip
                counter--;
                if (counter == 0) {
                    // return when found nth div
                    return sibling;
                }
            }
        }
        return null;
    }

我还有第三个想法,使用类型(2)的h2:contains(“text”)~div:nth。它对第一种情况有效,但对第二种情况无效,可能是因为有一个

 类似资料:
  • 我尝试使用Firebase为Android提供推送通知。但我面临着非常奇怪的问题。当我在前台发送推送时,一切正常。当我在后台发送推送时(我只发送数据),一切都正常,直到我回到前台,然后回到后台。 当我的应用程序第二次转到后台时,不会调用我的FirebaseMessagingService。另外,请注意,我使用的是Android Emulator。代码: AndroidManifest。xml: 服

  • 你有什么想法,我怎么能得到字符串的第二个点后的第一个字符。 在第一种情况下,我应该得到,在第二种情况下我应该得到。我考虑用点分割字符串,并提取第三个元素的第一个字符。但这似乎很复杂,我认为还有更好的方法。

  • 大家好我有这样一个问题,我有2个异步功能。我只想在第一次完全结束后,运行第二次。这就是我试图做的: null null 但它并不总是起作用的,有时第二个函数的代码运行在第一个函数的代码之前,我不确定为什么,我用await强制第二个只在第一个结束之后。 我现在只想让第一个函数结束来激活第二个函数。

  • 问题内容: 我试图从所有内容都在一个列中的地址中提取状态,这是一个示例: 我一直在尝试找出如何使用和一起做,但是我似乎无法掌握。这是我到目前为止的内容: 我以为它会从第二个逗号开始,到第三个逗号结束,并且让我的所有内容介于两者之间,但事实并非如此。 任何帮助表示赞赏。 问题答案: 一般来说, 例子:

  • 问题内容: 我有一个JavaScript函数,该函数使用jQuery发出两个连续的Ajax请求。我想确保在调用第二个函数之前已加载第一个请求。有办法吗? 问题答案: 在选项中指定,或在第一个调用的回调中进行第二个ajax 调用。