c# - 网页上的按钮不可点击
问题描述
前段时间我问过一个问题,但我在尝试解析网页时仍然面临随机错误。场景是系统转到https://www.sprouts.com/store/tx/plano/plano/点击“查看这家商店的特价商品”导航到https://shop.sprouts.com/shop/flyer和提取商店特价商品。目前,下面的代码仅在 10% 或 20% 的情况下有效,因为它无法找到要单击的按钮并导航到下一页。我究竟做错了什么?
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using SeleniumExtras.WaitHelpers;
[TestClass]
public class UnitTest1
{
ChromeDriver driver;
WebDriverWait webDriverWait;
[TestInitialize]
public void Startup()
{
var chromeOptions = new ChromeOptions();
//chromeOptions.AddArguments("headless");
chromeOptions.AddArguments("--proxy-server='direct://'");
chromeOptions.AddArguments("--proxy-bypass-list=*");
//chromeOptions.AddUserProfilePreference("disable-popup-blocking", "true");
//chromeOptions.AddArguments("--disable-extensions");
chromeOptions.AddArguments("--start-maximized");
var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
ChromeDriverService chromeDriverService = ChromeDriverService.CreateDefaultService(path);
driver = new ChromeDriver(chromeDriverService, chromeOptions);
webDriverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
}
[TestCleanup]
public void CleanUp()
{
driver.Quit();
}
[TestMethod]
public void GetSproutsWeeklyAdDetails()
{
try
{ driver.Navigate().GoToUrl("http://www.sprouts.com/store/tx/plano/plano/");
}
catch (TimeoutException timeoutException)
{
driver.Navigate().Refresh();
}
webDriverWait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));
**var elements1 = webDriverWait.Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(
By.XPath("//div[@class='cell small-6 divider']/button")));
elements1.First().Click();**
<= the system is unable to find the button 80% of the times
webDriverWait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));
var elements2 = webDriverWait.Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(
By.XPath("//li[@class='cell-wrapper' and @ng-repeat='item in items track by $index']")));
//More code below
}
}
}
不可点击按钮所在区域的源代码:
<div class="cell small-6 divider">
<button onclick="viewStoreFlyer(event, 101)">
<img src="https://www.sprouts.com/wp-content/themes/FoundationPress/dist/assets/images/weekly-specials-stores-icon.svg" width="32" alt="" role="presentation">
<br>
View this store’s specials
</button>
</div>
解决方案
在我看来,代码几乎是好的,除了两件事。您正在等待所有元素都可见,然后立即想要单击其中的第一个。首先在网站上只有一个元素跟随xPath,所以不需要定位列表。第二个是 - 当元素可见时,并不意味着它是可点击的,因此更好的处理方法是:
webDriverWait.Until(ExpectedConditions.ElementToBeClickable(By.XPath("//div[@class='cell small-6 divider']/button")));
PS: @DebanjanB 提供的答案在这种情况下非常好,因为您只想提取文本而不与元素交互。在我们的例子中,我们必须等到元素准备好接收点击,这就是为什么ElementToBeClickable
在这种情况下更好。