一尘不染

如何使用许多OR替代项来缩短XPath长表达式?

selenium

我正在努力让Selenium经历大量替代条件XPath,寻找 可能匹配的 元素,并将其传递给对象elmnt

当前,使用OR运算符(|),代码很快变得非常重复和详尽,特别是当存在很多可能的变化时。

在下面的例子中,唯一的变化是,我开始寻找h1h2h3。其余部分相同。

for word in ["testString1", "testString2", "testString3"]:

    try:
        elmnt = driver.find_element_by_xpath(
                                            (
                                                "//h1[text()[contains(., '%s')]]" % word + 
                                                "/following::p" + 
                                                "|" + 
                                                "//h1[text()[contains(., '%s')]]" % word + 
                                                "/following::span" +

                                                "|" +

                                                "//h2[text()[contains(., '%s')]]" % word + 
                                                "/following::p" + 
                                                "|" + 
                                                "//h2[text()[contains(., '%s')]]" % word + 
                                                "/following::span" +

                                                "|" +

                                                "//h3[text()[contains(., '%s')]]" % word + 
                                                "/following::p" + 
                                                "|" + 
                                                "//h3[text()[contains(., '%s')]]" % word + 
                                                "/following::span"
                                            )
                                            ).text
    except:
        pass
    else:
        print elmnt
        break

但在我实际的代码,我将寻求更加变化,包括在不同的节点类型/following::,除了pspan

问题: 有什么方法可以简化(缩短)该过程吗?

我的第一个希望是,可以做类似的事情:

"//[h1|h2|h3][text()[contains(., '%s')]]" % word

即可以将or运算符“嵌入” XPath表达式中,而不必像示例中那样使用完全详尽的字符串连接。如果是这样的话,该想法可能已经被广泛应用。

但是,这似乎是不可能的。

是创建某种生成函数来创建整个xPath字符串的解决方案,还是其他解决方案?


阅读 389

收藏
2020-06-26

共1个答案

一尘不染

我将使用缩短的XPath(利用@alecxe在注释中self::建议的轴):

  "//*[self::h1 or self::h2 or self::h3][contains(., '%s')]" % word
+ "/following::*[self::p or self::span]"

请注意,这个测试的 字符串值_的h1,或者h2,或者h3包含的值word变量(而不是直接文本节点的字符串值)。另外,如果你想真正的测试,这些元素的字符串值 _是 不是_包含_ word,使用[.='%s']来代替。

2020-06-26