【问题标题】:Not able to detect the element and send input to the Credit Card Number field through Selenium无法通过 Selenium 检测元素并将输入发送到信用卡号字段
【发布时间】:2018-10-05 15:23:00
【问题描述】:

我正在尝试在 this website 上自动执行结帐流程。我处于第四阶段,您点击“付款信息”中的“信用卡”选项,我正在尝试send_keys 输入我的信用卡号码。

但是,我注意到在单击 CC 选项后,页面会加载一段时间,因此我使用了显式等待该元素,但这不起作用。任何帮助将不胜感激。

ccNumber = session.find_element_by_css_selector('input[name=credit-card-number]')
wait = WebDriverWait(session, 100)
wait.until(EC.element_to_be_selected(ccNumber))

这是错误:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"input[name=credit-card-number]"}

【问题讨论】:

  • 尝试将元素定义为ccNumber = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "input[name=credit-card-number]")))
  • @Andersson 现在甚至没有单击信用卡按钮(输入),并且在 webdriver 完成执行后不久就会引发错误。 raise TimeoutException(message, screen, stacktrace) 来自您上面建议的行
  • 正如安德森所说,您需要在单击按钮之前等待,而不是之后。也许他的方法不对,但你必须找到一个你可以等待的元素,并将其作为你的标准。
  • 你能验证css选择器是否正确吗?并在 html 中找到元素
  • @KirilS。我发现信用卡 div 的样式属性在按下信用卡按钮后从 style="display: none 变为空。是否可以使用该标准,以及如何使用?

标签: python selenium selenium-webdriver css-selectors webdriverwait


【解决方案1】:

Credit Card 号码的 <input> 字段在 <iframe> 内,因此您必须:

  • 让 WebDriverWait 等待所需的框架可用并切换到它
  • 诱导 WebDriverWait 使所需的元素可点击,您可以使用以下解决方案:
  • 代码块:

    WebDriverWait(session, 20).until(EC.frame_to_be_available_and_switch_to_it((By.ID,"braintree-hosted-field-number")))
    WebDriverWait(session, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.number#credit-card-number"))).send_keys("0000000000000000")
    

【讨论】:

  • 现在我已经到了最后一步并单击了下订单,但它会无限加载。你有什么想法为什么?是因为 selenium 作为浏览器而不是常规浏览器吗?
  • 完成!您还知道为什么付款步骤无限加载并且没有完成吗? chrome 驱动程序和 chrome 之间是否存在可能导致此问题的差异?应该有一个弹出窗口说卡无效
  • 付款步骤中的哪个确切步骤会导致此问题?付款提交?
  • 似乎需要额外的步骤。请问您能否针对您的新要求提出一个新问题?
【解决方案2】:

您可以等到加载微调器不再出现在页面上,然后再检查信用卡输入。我们有一个 C# 解决方案,您可以尝试适应 python,在其中循环等待元素显示,捕获异常直到超时。

    //Assert an element is displayed before the timeout milliseconds run out.
    public void AssertElementIsDisplayed(int timeout, IWebElement element, string elementName = "element")
    {
        Action<IWebElement> target = delegate (IWebElement e) {
            if (e == null)
            {
                throw new AssertionException("Failed to find " + elementName + ". It is null");
            }
            if (!e.Displayed)
            {
                elementName = (elementName == "element" && !String.IsNullOrEmpty(e.GetAttribute("title"))) ? e.GetAttribute("title") : elementName;
                throw new AssertionException("Expected (" + elementName + ") to be displayed but it was not");
            }
        };
        AssertInLoop(element, (long)timeout, 100L, target);
    }

    //Assert some Action on a WebElement for as long as the timeoutMillis allow.
    private void AssertInLoop(IWebElement element, long timeoutMillis, long millisBetweenAttempts, Action<IWebElement> callable)
    {
        AssertionException lastAssertionError = null;
        WebDriverException lastWebDriverException = null;

        long startTime = DateTimeOffset.Now.Ticks / TimeSpan.TicksPerMillisecond;
        if (timeoutMillis < 500 || timeoutMillis > 120 * 1000)
        {
            throw new ArgumentException("Timeout outside expected range. timeout_millis=" + timeoutMillis);
        }

        long millisLeft = timeoutMillis;

        while (millisLeft >= 1)
        {
            long lastAttemptStartMillis = DateTimeOffset.Now.Ticks / TimeSpan.TicksPerMillisecond;
            try
            {
                callable(element);
                return;
            }
            catch (AssertionException e)
            {
                lastAssertionError = e;
                lastWebDriverException = null;
            }
            catch (StaleElementReferenceException e)
            {
                lastAssertionError = null;
                lastWebDriverException = e;
            }
            catch (NotFoundException e)
            {
                lastAssertionError = null;
                lastWebDriverException = e;
            }
            catch (SystemException e)
            {
                throw e;
            }


            long elapsedMillis = (DateTimeOffset.Now.Ticks / TimeSpan.TicksPerMillisecond) - startTime;
            millisLeft = timeoutMillis - elapsedMillis;

            if (millisLeft >= 1)
            {
                long millisElapsedDuringThisAttempt = (DateTimeOffset.Now.Ticks / TimeSpan.TicksPerMillisecond) - lastAttemptStartMillis;
                long millisToSleep = millisBetweenAttempts - millisElapsedDuringThisAttempt;
                if (millisToSleep > 0)
                {
                    Thread.Sleep((int)millisToSleep);
                }
            }
        }

        if (lastAssertionError != null)
        {
            throw lastAssertionError;
        }
        else if (lastWebDriverException != null)
        {
            throw lastWebDriverException;
        }
    }

【讨论】:

    猜你喜欢
    • 2021-08-06
    • 2019-10-20
    • 2020-11-30
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 2018-09-21
    • 2021-02-27
    相关资源
    最近更新 更多