获取元素的最小XPath

时间:2016-12-29 20:09:19

标签: python html python-2.7 xpath web-scraping

我试图创建一个返回元素 XPATH 的函数。不幸的是,它返回的绝对xpath是不够的。

我希望尽可能获得最小的xpath(或更好 - 更多"聪明",不一定是最小的)。例如,如果element有id,则返回xpath依赖于其id。

我想多次使用此xpath,并且根据页面更改,绝对xpath非常容易受到攻击。

或者,如果它的父母有id,则返回父母xpath by id和concat with /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] / DIV [2] /格[ 1] / DIV / DIV [1] / DIV [2] / DIV [2] / DIV [2] / DIV [1] / DIV [1] /表/ TR [6] / TD [2] / DIV [1 ]

你知道怎么做吗?

1 个答案:

答案 0 :(得分: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() + "]"
}