【问题标题】:"TypeError: 'str' object is not callable" using WebDriverWait for link_text in Selenium through Python“TypeError:'str'对象不可调用”通过Python在Selenium中使用WebDriverWait for link_text
【发布时间】:2020-11-06 19:30:22
【问题描述】:

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

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

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

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?或者这根本就是问题所在?

这让我发疯了,非常感谢您的帮助!

【问题讨论】:

    标签: python selenium webdriverwait expected-condition linktext


    【解决方案1】:

    您的研究方向正确。

    在您的第一个用例中,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() 应该在 tuple 中调用,因为它不是一个函数,而是一个,其中初始化程序只需要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() takes 2 positional arguments but 3 were given using WebDriverWait and expected_conditions as element_to_be_clickable with Selenium Python找到详细讨论

    【讨论】:

    • 非常感谢您!我将更多地研究 WebDriverWait 的细节。但是,此解决方案的一个问题是WebDriverWait(driver, 12).until(EC.element_to_be_clickable((By.LINK_TEXT, "Mehr erfahren"))).click() 会导致 TimeoutException,即使我显着增加了等待时间。这是否意味着这个元素根本不可点击?我不明白这是怎么回事,因为我可以正常点击它。
    • @Spencer 不知何故我错过了你的评论。由于找不到元素,您会看到 TimeoutException 异常。您可能必须使用其他一些定位器策略,或者可能必须改进现有的定位器策略。你可以提出一个包含所有细节的新问题。 SO 贡献者将很乐意为您提供帮助。
    【解决方案2】:

    我想我找到了你的问题here。从源头

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

    until 采用方法(即可调用的东西)。因此,当driver.find_element_by_link_text("Mehr erfahren").click() 引发异常时,它将尝试调用...until("Mehr erfahren")...。因为until 需要一个方法,它会尝试调用你给它的字符串——引发让你发疯的错误:)

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        这可用于您的两个网址。

        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')
        

        查看文档here了解如何使用WebDriverWait

        【讨论】:

          猜你喜欢
          • 2019-08-24
          • 2023-01-15
          • 2022-01-08
          • 2020-04-11
          • 2020-09-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多