我正在努力让Selenium经历大量替代条件XPath,寻找 可能匹配的 元素,并将其传递给对象elmnt。
elmnt
当前,使用OR运算符(|),代码很快变得非常重复和详尽,特别是当存在很多可能的变化时。
OR
|
在下面的例子中,唯一的变化是,我开始寻找h1,h2或h3。其余部分相同。
h1
h2
h3
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::,除了p和span。
/following::
p
span
问题: 有什么方法可以简化(缩短)该过程吗?
我的第一个希望是,可以做类似的事情:
"//[h1|h2|h3][text()[contains(., '%s')]]" % word
即可以将or运算符“嵌入” XPath表达式中,而不必像示例中那样使用完全详尽的字符串连接。如果是这样的话,该想法可能已经被广泛应用。
or
但是,这似乎是不可能的。
是创建某种生成函数来创建整个xPath字符串的解决方案,还是其他解决方案?
我将使用缩短的XPath(利用@alecxe在注释中self::建议的轴):
self::
"//*[self::h1 or self::h2 or self::h3][contains(., '%s')]" % word + "/following::*[self::p or self::span]"
请注意,这个测试的 字符串值_的h1,或者h2,或者h3包含的值word变量(而不是直接文本节点的字符串值)。另外,如果你想真正的测试,这些元素的字符串值 _是 不是_包含_ word,使用[.='%s']来代替。
word
[.='%s']