关于python:单击基于部分文本匹配的链接

Clicking a link based on partial text match

我将Selenium2/WebDriver与Python结合使用,我想单击以字符串开头的第一个链接。我想到的代码是:

1
2
3
4
def click_link_partial(div_id, partial):
  linkdiv = driver.find_element_by_id(div_id)
  z = (a.click() for a in linkdiv.find_elements_by_tag_name('a') if a.text.startswith(partial))
  z.next()

我不太熟悉Python中的生成器。为什么不立即调用.click(),而不是在执行z.next()时调用?

使用这个代码有什么缺点吗?


首先,请您熟悉Python的生成器,它们是您的Python库中非常强大的工具。托马斯·沃特斯的一个很好的解释可以通过阅读另一个问题找到:您可以使用Python生成器函数做什么?

一旦你读完了,你就会意识到生成器只是给你一个延迟计算表达式的能力。

将这段信息与上面的代码关联起来,您会发现a.click()实际上不会立即执行,因为预期您会迭代生成器表达式,这就是您创建的表达式。这就是为什么您必须发出z.next()来实际调用click()方法的原因。

如果您不想发布z.next(),并且假设您只想单击第一个部分匹配的链接,那么您将按如下方式重新编写上面的代码:

1
2
3
4
5
6
def click_link_partial(div_id, partial):
  linkdiv = driver.find_element_by_id(div_id)
  for a in linkdiv.find_elements_by_tag_name('a'):
      if a.text.startswith(partial):
         a.click()
         break  # stop iterating over the partially matched elements.

但是,如果要单击所有部分链接的元素,那么应该从上面的代码中删除z.next(),并返回要在外部函数/方法中使用的生成器表达式。下面是一个例子:

1
2
3
4
5
6
7
8
def click_link_partial(div_id, partial):
  linkdiv = driver.find_element_by_id(div_id)
  return (a for a in linkdiv.find_elements_by_tag_name('a')
            if a.text.startswith(partial))

for matched_clickable_anchor in click_link_partial('#some-div-id', 'spam'):
    matched_clickable_anchor.click()  # do click
    # do something else.

希望这有帮助!