2016-12-29 99 views
4

我正在尝试创建一个函数,它返回一个元素的XPATH。不幸的是,它返回的绝对xpath不够。获取元素的最小XPath

我想获得尽可能小的xpath(或更好 - 更“聪明”,不一定最小)。例如,如果元素具有id,则返回xpath取决于其id。

我想多次使用这个xpath,绝对xpath根据页面变化很容易受到攻击。

或者,如果它的父母有ID,然后返回父母XPath ID和连接/child

lxml模块或其他模块可能吗?

例如XPath帮助程序向导扩展可以做得更好。

def _load_root(url): 
    r = requests.get(url) 
    r.encoding = 'utf-8' 
    html = r.content 
    return etree.fromstring(html, etree.HTMLParser()) 

def get_xpath_by_text(text,url): 
    root = _load_root(url) 
    e = root.xpath('.//*[contains(text(),"{}")]'.format(text)) 
    print root.getpath(e) 

/HTML /体/格[1]/DIV [1]/DIV [1]/DIV [2]/DIV [1]/DIV [1]/DIV [2] /格[2]/DIV [1]/DIV/DIV [1]/DIV [2]/DIV [2]/DIV [2]/DIV [1]/DIV [1] /表/ TR [6]/TD [ 2]/div [1]

你知道该怎么做吗?

回答

1

就我所见,您正在询问两个矛盾的事情:一个最小的XPath和一个对文档变更稳定的XPath。

元素的最小XPath通常类似(//*)[134],但这对文档更改非常敏感。

你可以得到相对于最近的祖先用一个ID(的XPath)使用递归算法类似属性:

function minimalXpath(Node node) { 
    if (exists(node/@id)) 
    then "id(" + node/@id + ")" 
    else if (node is root) 
    then "" 
    else minimalXPath(node.getParent()) + "/" + node.getName() + 
    "[" + node.getSiblingPosition() + "]" 
} 
+0

谢谢迈克尔的回答。我发现一个术语“最小路径”与我想达到的最接近。您的答案通过ID解决了问题,但还有更多情况。例如,很常见的是class =“price”或itemprop =“price”等等。所以我不能只依赖于id(这是最好的选择),因为很多时候没有id,但仍然有比绝对更好的“锚”路径。 –