注意我创造了术语“水平深度”来测量树内节点的子维度。
所以想象一下,它的 xpath 类似于 /html/table/tbody/tr/td,并且“水平深度”为 5
我想看看是否有一种方法可以根据这个水平深度来识别和选择元素。
如何找到最大深度?
如果您需要深度 >= 5 的所有节点:
/*/*/*/*//*
如果您需要深度 == 5 的所有节点:
/*/*/*/*/*
其实有一个XPath函数
count
,你可以将它与ancestor
轴结合起来:
//*[count(ancestor::*) >= 4]
我认为“垂直深度”和“水平深度”是不明确的。有什么理由不使用 XPath 中已经存在的轴术语,并引用“祖先的数量”和“先前兄弟的数量”?它稍微冗长一些,但不多,a) 明确,b) 术语映射到
count(ancestor::*)
和 count(preceding-sibling::*)
。
我知道这个问题已经很老了,但我们开始吧:
查找特定元素深度的函数:
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 分钟)来处理,具体取决于节点数量和您的计算机。