1

这是我在 Stack Overflow 上的第一篇文章。我一直在浏览和搜索关于 SO 的这个问题的所有可能答案,我想此时我应该问一个问题,因为我已经在这堵墙上好几天了。我目前正在使用 Python 中的 Selenium 进行网络抓取项目。我已经抓取了一个网站,目前正在第二个网站上,我遇到了一个看似棘手的问题。以下代码运行良好,页面https://www.spd.de/standpunkte/上没有错误:

try:
    driver.find_element_by_link_text("Familien").click()
except NoSuchElementException:
    WebDriverWait(driver, 12).until("Familien").click()

同时,以下代码TypeError: 'str' object is not callable在页面https://www.spd.de/standpunkte/familie/上引发错误:

try:
    driver.find_element_by_link_text("Mehr erfahren").click()
except NoSuchElementException:
    WebDriverWait(driver, 12).until("Mehr erfahren").click()

错误发生就行了WebDriverWait(driver, 12).until("Mehr erfahren").click()。根据我迄今为止的研究,我认为具体问题是这一行中的某些东西被解释为一个str对象,因此无法调用。在我看来,有两个问题:

  1. 我看不出有任何理由让这条线产生错误,而顶部的代码,抓取同一个网站,但在不同的页面上,没有问题。我检查并确保页面上没有被点击的隐藏元素。

  2. 我不知道该行中的什么被视为str对象。全线?只有一部分?如果有,是哪一部分?加剧这一点的是,我无法真正打破界限以查看有关它的任何信息。两者都print(WebDriverWait(driver, 12).until("Mehr erfahren").click())最终print(type(WebDriverWait(driver, 12).until("Mehr erfahren").click()))给出错误。我能够确定该.click()方法不是问题,因为我尝试将行设置为等于一个变量,然后与该变量进行交互,但这仍然会在与以前相同的行上产生错误;它甚至从未与该.click()方法达成一致。

有什么方法可以确定该行的哪一部分被解释为str?或者这根本就是问题所在?

这一直让我发疯,因此将不胜感激!

4

4 回答 4

0

我认为直到需要一个条件(并且 WebDriverWait 等到该条件为真)。您只是将字符串作为参数而不是条件传递。您需要一个条件来检查页面上是否存在该元素。

于 2020-07-17T03:14:20.890 回答
0

您可以使用这个 css 选择器:a[href*="familien"]

这可用于您的两个 URL。

driver.get('yourURL')
try:
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'a[href*="familien"]'))).click()
except NoSuchElementException:
    # handle if the element not exist
    print('element not exist')

请参阅此处的文档以了解如何使用WebDriverWait

于 2020-07-17T04:03:14.560 回答
0

我想我在这里找到了你的问题。从源头

def until(self, method, message=''):
    ...

until接受一个方法(即可以调用的东西)。因此,当driver.find_element_by_link_text("Mehr erfahren").click()引发异常时,它将尝试调用...until("Mehr erfahren").... 由于until期望一个方法,它会尝试调用你给它的字符串 - 引发让你发疯的错误:)

于 2020-07-17T03:11:38.087 回答
0

你的研究方向是对的。

在您的第一个用例中,其中的行try是成功的:

driver.find_element_by_link_text("Familien").click()

所以里面的行except从来没有被调用过:

WebDriverWait(driver, 12).until("Familien").click()

因此,您看不到错误。


在您的第二个用例中,其中的行try不成功:

driver.find_element_by_link_text("Familien").click()

所以里面的行except被称为:

WebDriverWait(driver, 12).until("Mehr erfahren").click()

这导致错误:

TypeError: 'str' object is not callable

深潜

WebDriverWaitexpected_conditions结合调用。

您可以在以下位置找到一些详细的讨论:

现在,element_to_be_clickable()应该在 a 中调用tuple它,因为它不是函数而是,其中初始化程序只需要隐式self之外的1 个参数:

class element_to_be_clickable(object):
    """ An Expectation for checking an element is visible and enabled such that you can click it."""
    def __init__(self, locator):
        self.locator = locator

    def __call__(self, driver):
        element = visibility_of_element_located(self.locator)(driver)
        if element and element.is_enabled():
            return element
        else:
            return False

所以而不是:

WebDriverWait(driver, 12).until("Mehr erfahren").click()

您需要(添加额外的括号):

WebDriverWait(driver, 12).until((EC.element_to_be_clickable(By.LINK_TEXT, "Mehr erfahren"))).click()

您可以在init ()中找到详细讨论,其中包含2 个位置参数,但 3 个是使用 WebDriverWait 和 expected_conditions as element_to_be_clickable 与 Selenium Python 给出的

于 2020-07-17T09:10:53.080 回答