org.openqa.selenium.NoSuchElementException:尝试通过 CssSelector 定位 card-fields-iframe 时,返回的节点 (null) 不是 DOM 元素

2024-02-27

我正在尝试通过部分 id 来定位 iframe。对于这个方法,我使用了:driver.switchTo().frame(driver.findElement(By.cssSelector("iframe[id*='card-fields-number']")));我也尝试过xpath。

 driver.switchTo().frame(driver.findElement(By.xpath("//iframe[contains(@id,'card-fields-number')]")));

但是,我仍然收到此异常:

org.openqa.selenium.NoSuchElementException: Returned node (null) was not a DOM element

我发现当我为 HtmlUnit 启用 javascript 时,它能够找到框架并切换到它。我宁愿不启用 javascript,因为它对我来说运行速度非常慢,并且增加了不必要的延迟。

iFrame HTML 代码:

<iframe class="card-fields-iframe" frameborder="0" id="card-fields-number-7pbvqg7azsf00000" name="card-fields-number-7pbvqg7azsf00000" scrolling="no" src="https://checkout.shopifycs.com/number?identifier=438599641d0ed8fe61c161d72e62b5f8&amp;location=https%3A%2F%2Fshopnicekicks.com%2F2192362%2Fcheckouts%2F438599641d0ed8fe61c161d72e62b5f8&amp;dir=ltr&amp;fonts[]=Lato" title="Field container for: Card number" style="height: 43px;"></iframe>

iFrame ID 是动态的,所以这就是我使用部分 ID 的原因。

网站链接:https://shopnicekicks.com/checkout https://shopnicekicks.com/checkout您必须填写所有内容,直到到达最后一页,即信用卡信息页。

UpdateiFrame 位于父框架内部。 父框架:

<iframe srcdoc="<script>!function(){var e=function(e){var t={exports:{}};return e.call(t.exports,t,t.exports),t.exports},t=function(){function e(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,&quot;value&quot;in i&amp;&amp;(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(t,n,i){return n&amp;&amp;e(t.prototype,n),i&amp;&amp;e(t,i),t}}(),n=function(e,t){if(!(e instanceof t))throw new TypeError(&quot;Cannot call a class as a function&quot;)},i=function(e){return e&amp;&amp;e.__esModule?e:{&quot;default&quot;:e}},o=e(function(e,i){&quot;use strict&quot;;Object.defineProperty(i,&quot;__esModule&quot;,{value:!0});var o=function(){function e(){var t=this;n(this,e),this.calls=[],window.ga=function(){for(var e=arguments.length,n=Array(e),i=0;i<e;i++)n[i]=arguments[i];return t.gaCall(n)}}return t(e,[{key:&quot;gaCall&quot;,value:function(e){var t=this;this.calls.push(e),clearTimeout(this.timeout),this.timeout=setTimeout(function(){t.calls.length>0&amp;&amp;t.sendMessage()},0)}},{key:&quot;listen&quot;,value:function(){var e=this;window.addEventListener(&quot;message&quot;,function(t){return e.receiveMessage(t)},!1)}},{key:&quot;sendMessage&quot;,value:function(){window.parent.postMessage({type:&quot;analytics&quot;,calls:this.calls},this.origin),this.calls=[]}},{key:&quot;receiveMessage&quot;,value:function(e){if(e.source===window.parent&amp;&amp;&quot;checkout_context&quot;===e.data.type){this.origin=e.origin,window.Shopify=e.data.Shopify,window.__st=e.data.__st;try{window.additionalScripts()}catch(e){console.error(&quot;User script error: &quot;,e)}}}}]),e}();i[&quot;default&quot;]=o});e(function(){&quot;use strict&quot;;var e=i(o);!function(){(new e[&quot;default&quot;]).listen()}()})}(&quot;undefined&quot;!=typeof global?global:&quot;undefined&quot;!=typeof window&amp;&amp;window); window.additionalScripts = function () {};</script>" src="https://checkout.shopify.com/2192362/sandbox/google_analytics_iframe" onload="this.setAttribute('data-loaded', true)" sandbox="allow-scripts" id="google-analytics-sandbox" tabindex="-1" class="visually-hidden" style="display:none" aria-hidden="true" data-loaded="true"></iframe>

这个错误信息...

org.openqa.selenium.NoSuchElementException: Returned node (null) was not a DOM element

...意味着有没有这个元素发现返回的节点是null或者不是 DOM 元素。

这还是一个开放的issue https://github.com/SeleniumHQ/htmlunit-driver/issues/32 with htmlunit 驱动程序 team.

但是,您需要注意以下一些事项:

  • 首先也是最重要的,所有现代浏览器都内置了对 JavaScript 的支持。
  • HtmlUnitDriver https://github.com/SeleniumHQ/htmlunit-driver is a WebDriver compatible driver for HtmlUnit http://htmlunit.sourceforge.net/ headless browser. It has fairly good JavaScript support (which is constantly improving) and is able to work even with quite complex AJAX libraries, simulating Chrome, Firefox or Internet Explorer depending on the configuration used. So ideally while working with HtmlUnitDriver, JavaScript must be enabled, else HtmlUnitDriver may not ne able to detect the JavaScript based elements.
    • 您可以在中找到详细的讨论从 url 导航页面时,HtmlUnitDriver 不加载 javascript https://stackoverflow.com/questions/53724856/htmlunitdriver-does-not-load-javascript-when-navigating-a-page-from-an-url/53744963#53744963
  • The element seems to be a credit card field and historically Credit Card Number, etc resides within <iframes>.
    • 您可以在中找到详细的讨论无法使用selenium python找到信用卡号码的元素 https://stackoverflow.com/questions/54030701/unable-to-locate-element-of-credit-card-number-using-selenium-python/54039805#54039805
  • Whenever an <iframe> is in play src attribute of the <iframe> tag plays a vital role.
    • 您可以在中找到详细的讨论iframe下处理#document的方法 https://stackoverflow.com/questions/53203417/ways-to-deal-with-document-under-iframe
  • As per best practices while switching <iframe> you need to induce WebDriverWait for the desired frame to be available and switch to it.
    • 我们在你之前的问题中已经讨论过这方面的问题Selenium 无法定位 iframe https://stackoverflow.com/questions/54576206/selenium-cant-locate-iframe

因此,您可以使用以下任一解决方案:

  • CSS选择器:

    new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.cssSelector("iframe.card-fields-iframe[id^='card-fields-number-'][src*='shopifycs']")));
    
  • xpath:

    new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//iframe[@class='card-fields-iframe' and starts-with(@id,'card-fields-number-')][contains(@src, 'shopifycs')]")));
    

Update

查看快照CssSelector它根据您提供的 HTML 识别元素 Perfecto:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

org.openqa.selenium.NoSuchElementException:尝试通过 CssSelector 定位 card-fields-iframe 时,返回的节点 (null) 不是 DOM 元素 的相关文章

随机推荐