提问者:小点点

单击链接<a href="javascript:;"…>使用Selenium chromeriver在C#中返回错误“元素不可见”


我有一个带有div内链接的网站。网页中的html源检查如下所示:

<div class="add-to-cart-wrapper">
    <button data-tooltip="Only investments from the selected page will be sold." data-theme="dark" data-placement="top" data-tooltip-trigger="hover" data-id-list="48999040" class="btn btn-default tooltip-item trigger-sell-all">
        Sell All
    </button>
    <a href="javascript:;" data-tooltip="Remove all investments from sale" data-placement="top" data-theme="dark" data-tooltip-trigger="hover" data-currency-iso-code="978" class="trigger-remove-all-sales">
        <i class="fas fa-reply-all fa-flip-vertical"></i>
    </a>
</div>

在浏览器中,它看起来像这样:

我实际上试图归档的是单击“全部出售”按钮下方的这两个灰色箭头。它与匹配

不幸的是,Selenium(Chromeriver)的以下C#代码返回该元素当前不可见,如果我可以在浏览器中手动单击它:

var link = buttonWrapper.FindElement(By.ClassName("trigger-remove-all-sales"));
link.Click();

错误消息如下所示:

OpenQA. Selenium.ElementNotVisibleException:'元素不可见
(会话信息:chrome=68.0.3440.106)(驱动程序信息:chromeriver=2.41.578737(49da6702b16031c40d63e5618de03a32ff6c197e),平台=Windows NT 10.0.17134x86_64)'

对如何进行有任何建议吗?

编辑:根据建议,我按照以下代码添加了“等待。直到("元素x可见")”。不幸的是,我遇到了超时错误:

new WebDriverWait(browser, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.CssSelector("div.add-to-cart-wrapper a.trigger-remove-all-sales[data-tooltip='Remove all investments from sale']"))).Click();

OpenQA. Selenium.WebDriverTimeoutException:“20秒后超时”

根据建议,我试图找到元素。FindElement()我注意到的是属性显示=false

我在两者之间添加了一个Thread. S睡眠(120000),并重新查找代码以查看会发生什么变化。这是测试代码:

var buttonWrapper = browser.FindElement(By.ClassName("add-to-cart-wrapper"));
var link = buttonWrapper.FindElement(By.ClassName("trigger-remove-all-sales"));
Thread.Sleep(120000);
buttonWrapper = browser.FindElement(By.ClassName("add-to-cart-wrapper"));
link = buttonWrapper.FindElement(By.ClassName("trigger-remove-all-sales"));

即使在2分钟的等待时间后,找到了元素,但仍显示为Display=false

有一个事件监听器可以使用a. triper-Remove-all-sales


共3个答案

匿名用户

你必须等到元素不可见,它是java代码,你也可以使用任何定位器,无论是XPath还是id或类名

WebDriverWait wait = new WebDriverWait(driver, 15);
WebElement elem = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("")));
elem.click();

或者您也可以使用elementToBeClickable()方法

WebDriverWait wait = new WebDriverWait(driver, 15);
WebElement elem = wait.until(ExpectedConditions.elementToBeClickable(By.id("")));
elem.click();

将此代码转换为C夏普,因为我对它没有很好的熟练程度

匿名用户

我做了一个非常非常肮脏的变通方法,移动鼠标位置并单击位置而不是元素。

但是这个解决方案真的很脏,当网站上发生变化时容易出错。因此我不想将此标记为答案:

new Actions(browser).MoveToElement(link, 1225, 565).Click().Build().Perform();

要查看鼠标的实际位置,您可以在此行之前设置暂停/中断标记,打开Browser驱动程序,然后将以下js代码粘贴到开发人员控制台:

// Create mouse following image.
var seleniumFollowerImg = document.createElement("img");

// Set image properties.
seleniumFollowerImg.setAttribute('src', 'data:image/png;base64,'
+ 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAQAAACGG/bgAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAA'
+ 'HsYAAB7GAZEt8iwAAAAHdElNRQfgAwgMIwdxU/i7AAABZklEQVQ4y43TsU4UURSH8W+XmYwkS2I0'
+ '9CRKpKGhsvIJjG9giQmliHFZlkUIGnEF7KTiCagpsYHWhoTQaiUUxLixYZb5KAAZZhbunu7O/PKf'
+ 'e+fcA+/pqwb4DuximEqXhT4iI8dMpBWEsWsuGYdpZFttiLSSgTvhZ1W/SvfO1CvYdV1kPghV68a3'
+ '0zzUWZH5pBqEui7dnqlFmLoq0gxC1XfGZdoLal2kea8ahLoqKXNAJQBT2yJzwUTVt0bS6ANqy1ga'
+ 'VCEq/oVTtjji4hQVhhnlYBH4WIJV9vlkXLm+10R8oJb79Jl1j9UdazJRGpkrmNkSF9SOz2T71s7M'
+ 'SIfD2lmmfjGSRz3hK8l4w1P+bah/HJLN0sys2JSMZQB+jKo6KSc8vLlLn5ikzF4268Wg2+pPOWW6'
+ 'ONcpr3PrXy9VfS473M/D7H+TLmrqsXtOGctvxvMv2oVNP+Av0uHbzbxyJaywyUjx8TlnPY2YxqkD'
+ 'dAAAAABJRU5ErkJggg==');
seleniumFollowerImg.setAttribute('id', 'selenium_mouse_follower');
seleniumFollowerImg.setAttribute('style', 'position: absolute; z-index: 99999999999; 
pointer-events: none;');

// Add mouse follower to the web page.
document.body.appendChild(seleniumFollowerImg);

// Track mouse movements and re-position the mouse follower.
$(document).mousemove(function(e) {
$("#selenium_mouse_follower").css({ left: e.pageX, top: e.pageY });
});

在鼠标移动代码之后,您可以设置另一个断点来查看鼠标在浏览器中的实际移动位置。

提示:删除。单击(),这样您就不会意外单击链接。每次刷新页面时都必须重新加载鼠标跟踪脚本,因此当您单击链接时,您无法再跟踪鼠标。此外,该脚本仅在鼠标移动之前初始化时才有效。

匿名用户

我使用的解决方案是使用scriptexecator单击有效的元素:

var button = browser.FindElement(By.ClassName("add-to-cart-wrapper"));
((IJavaScriptExecutor)browser).ExecuteScript("arguments[0].click();", button);