在网页上无法点击按钮

时间:2018-07-17 02:53:38

标签: c# .net selenium selenium-chromedriver

一段时间以前,我曾问过question,但在尝试解析网页时仍然遇到随机错误。 场景是系统转到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>

2 个答案:

答案 0 :(得分:0)

就我的观点而言,该代码几乎是不错的,除了两点。您正在等待所有元素可见,然后立即要单击它们中的第一个。首先,在网站上只有跟随xPath的一个元素,因此无需查找列表。第二个是-当element可见时,它并不意味着它是可单击的,因此处理此问题的更好方法是:

webDriverWait.Until(ExpectedConditions.ElementToBeClickable(By.XPath("//div[@class='cell small-6 divider']/button"))); 

PS: 在这种情况下,@ DebanjanB提供的答案非常好,因为您只想在不与element交互的情况下提取文本。在我们的情况下,我们必须等到elelment准备好接受点击为止,这就是ElementToBeClickable在这种情况下更好的原因。

答案 1 :(得分:0)

我可以通过在单击按钮之前添加一个线程睡眠来使其工作。

var elements1 = webDriverWait.Until(ExpectedConditions.ElementToBeClickable(
        By.XPath("//div[@class='cell small-6 divider']/button")));
Thread.Sleep(2000);
elements1.Click();