如何获取节点的水平深度?

问题描述 投票:0回答:3

注意我创造了术语“水平深度”来测量树内节点的子维度。

所以想象一下,它的 xpath 类似于 /html/table/tbody/tr/td,并且“水平深度”为 5

我想看看是否有一种方法可以根据这个水平深度来识别和选择元素。

如何找到最大深度?

xml ruby xpath nokogiri
3个回答
4
投票

如果您需要深度 >= 5 的所有节点:

/*/*/*/*//*

如果您需要深度 == 5 的所有节点:

/*/*/*/*/*

其实有一个XPath函数

count
,你可以将它与
ancestor
轴结合起来:

//*[count(ancestor::*) >= 4]

2
投票

我认为“垂直深度”和“水平深度”是不明确的。有什么理由不使用 XPath 中已经存在的轴术语,并引用“祖先的数量”和“先前兄弟的数量”?它稍微冗长一些,但不多,a) 明确,b) 术语映射到

count(ancestor::*)
count(preceding-sibling::*)


0
投票

我知道这个问题已经很老了,但我们开始吧:

查找特定元素深度的函数:

from selenium import webdriver
from selenium.webdriver.common.by import By

def go_up(element):
    "Returns parent element of <element>."
    if element.tag_name == "body":
        return element
    else:
        old_e = element.tag_name
        parent = element.find_element(By.XPATH, "..")
        new_e = parent.tag_name
        #print("{} ^ {}".format(old_e, new_e))
        return parent

从元素走到主体并计算步数的函数:

def ancestors_to_root(element):
    """
    Returns <int> of number of steps <element> is from the BODY element ("horizontal" depth).
    """
    ancestors = 0
    depth = element.tag_name
    if element.tag_name == "body":
        #print("Ancestors to root: {} ({}).".format(ancestors, depth))
        return ancestors
    while True:
        element = go_up(element)
        ancestors += 1
        depth = element.tag_name + " < " + depth
        if element.tag_name == "body":
            #print("Ancestors to root: {} ({}).".format(ancestors, depth))
            return ancestors

比较所有深度并返回最高点:

def maximum_depth(element, is_page=True):
    
    if is_page: # from body (pass drive as argument)
        depths = [ancestors_to_root(e) for e in element.find_elements(By.XPATH, "//body//*")]
    else: # from context node (pass an element)
        depths = [ancestors_to_root(e) for e in element.find_elements(By.XPATH, ".//*")]
    if depths:
        all_depths = list(set(depths))
        print("Highest depth: ", max(all_depths))
    else:
        print("Highest depth: 0")

用法1:整个页面:

maximum_depth(drive)

用法2:特定元素内的深度:

h3 = b.find_element(By.XPATH, "//div[2]") # change to something in your page
maximum_depth(h3, is_page=False)

警告: maximum_depth() 将需要几分钟(在我的测试中超过 6 分钟)来处理,具体取决于节点数量和您的计算机。

© www.soinside.com 2019 - 2024. All rights reserved.