2016-12-29 111 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,但仍然有比絕對更好的「錨」路徑。 –