我用splinter编写了一些浏览器测试,并且有一个页面包含明确定义的行,其中包含自己的标题,按钮等。例如:
在我的特定情况下,我可以获得如下一行:
row = lambda title: browser.find_by_xpath("//div[@class='my-row'][contains(., '{0}')]".format(title))
row1 = row('Row 1')
row2 = row('Row 2')
然后,用这个lamba:
button = lambda elmt, text: elmt.find_by_xpath("//a[@class='btn'][contains(.,'{0}')]".format(text))
我可以磨练正确的常规按钮或说出类似的内容:
assert button(row1, 'Special button')
assert not button(row2, 'Special button')
但是当我调用按钮lambda时,它会返回其他行的按钮。
根据我的理解,通过此lamba查找xpath,“从elmt开始,查找嵌套在elmt 中的按钮包含给定文本”。因为我从其他行中获取的东西没有嵌套在当前的行中,但是我在这里缺少什么?
我的xpath出了什么问题?
答案 0 :(得分:1)
以//
开头的XPath表达式从文档的 root 节点开始,并选择节点而不管它们在文档中的位置。这种表达式的当前上下文节点,例如
//div
对返回的结果集没有影响。要从上下文节点开始搜索//
(descendant-or-self::)轴,您需要使用
.//div
在您的情况下,这意味着更改
button = lambda elmt, text: elmt.find_by_xpath("//a[@class='btn'][contains(.,'{0}')]".format(text))
到
button = lambda elmt, text: elmt.find_by_xpath(".//a[@class='btn'][contains(.,'{0}')]".format(text))
(警告:这都与你代码中的XPath表达有关,我不能对其余部分发表评论。)