我已经为此工作了几个小时,但似乎无法将所有部分放在一起...... 所以给出:
<a href="link1">link</a>
<span class="class_name">00A<span>
...
<a href="link2">link</a>
<span class="class_name">00B<span>
...
<a href="link3">link</a>
<span class="class_name">01B<span>
...
<a href="link4">link</a>
<span class="class_name">01A<span>
我试图根据 span 的内部文本获取链接。所以我知道... 我可以获得所有链接:
links = [my_elem.get_attribute("href") for my_elem in WebDriverWait(driver, 30).until(EC.visibility_of_all_elements_located((By.XPATH, "//span[contains(@class, 'class_name')]//preceding-sibling::a[@href]")))]
我可以通过以下方式获取单个跨度上的文本:
print(driver.find_element(By.XPATH, "//span[contains(@class, 'class_name')]").text)
但我无法使用 find 元素来获取所有文本进行测试,因为它要求列表的文本。 我应该能够使用:
[contains(text(), '\\d+[A]')]")
但我不知道如何将它与所有链接的代码结合起来。我觉得我忽略了一些非常愚蠢的事情,但现在是早上 6:30,我昨天晚上开始做这个项目,所以我放弃了,只是去问更聪明的人。预先感谢您的帮助。
注意
contains()
函数的第二个参数不是正则表达式;它是一个纯字符串,需要在第一个字符串参数中查找。我相信使用 Selenium 你会被 XPath 1.0 困住,它没有任何正则表达式函数。
在不使用正则表达式的情况下,如果您想过滤一组
span
元素以仅包含文本内容由一串数字后跟单个 A
组成的元素,则需要使用更复杂的表达式,其中组合了一堆字符串函数,例如像这样的东西:
span[
contains(., 'A') and
contains('0123456789', substring(., 1, 1)) and
translate(substring-before(., 'A'), '0123456789', '') = '' and
substring-after(., 'A') = ''
]
注意,
.
是对“上下文节点”的引用,在谓词表达式中表示 span
元素之一。
这个表达的意思是:
span
元素
A
字符;和A
之前的文本完全由数字组成;和A
之后没有任何文字(即最后只有一个 A
)顺便说一句,我不确定这个表达式是否符合您的想法:
//span[contains(@class, 'class_name')]//preceding-sibling::a[@href]
澄清一下:XPath 中的
//
是表达式 /descendant-or-self::node()/
的 缩写。所以你的表达式可以写成:
//span[contains(@class, 'class_name')]
/descendant-or-self::node()/preceding-sibling::a[@href]
这将返回每个
a
元素(具有 href
属性),后面跟着一个兄弟元素,即 either:
span
元素,其 class
属性为 'class_name'
; 或span
元素的后代,其 class
属性为 'class_name'
。如果您知道
span
和 a
实际上是兄弟姐妹,那么您可以将 //
替换为更简单的 /
(在我下面的建议中)。
这里要注意的另一件事是,除非每对
span
(或span
后代)和a
都包含在父元素中,否则preceding-sibling::a[@href]
步骤将返回a
元素在
span
之前,而不仅仅是第一个这样的
span
(我怀疑你想要做什么,因为我认为是在
span
之前的立即为链接提供了标签。你可以将谓词
[1]
应用于
a[@href]
元素集以仅获取第一个(按
preceding-sibling
顺序)。因此,为了结合这些想法,这是我的建议:
//span
[contains(@class, 'class_name')]
[
contains(., 'A') and
contains('0123456789', substring(., 1, 1)) and
translate(substring-before(., 'A'), '0123456789', '') = '' and
substring-after(., 'A') = ''
]
//preceding-sibling::a[@href][1]
应用于此输入:
<body>
<a href="link1">link</a>
<span class="class_name">00A</span>
...
<a href="link2">link</a>
<span class="class_name">00B</span>
...
<a href="link3">link</a>
<span class="class_name">01B</span>
...
<a href="link4">link</a>
<span class="class_name">01A</span>
</body>
...它产生:
<a href="link1">link</a>
<a href="link4">link</a>