【问题标题】:Select items from 3 dropdowns with dependency of first one从 3 个依赖于第一个的下拉列表中选择项目
【发布时间】:2019-04-21 13:58:05
【问题描述】:

我想做的是: 1- 访问这个网站:http://www.emlakyonetim.com.tr/tr-TR/sitelerimiz, 2- 点击第一个下拉菜单 - 点击一个城市,点击第二个下拉菜单 - 点击一个县,点击第三个下拉菜单。

简而言之,第二个下拉项依赖于第一个,第三个下拉项依赖于第二个。

代码(不完整):

@Test
public void SiteCek() throws InterruptedException
{
    driver.get("http://www.emlakyonetim.com.tr/tr-TR/sitelerimiz");
    Thread.sleep(2000);

    driver.findElement(By.id("select2-city-list-container")).click();

    List<WebElement> elm = driver.findElements(By.xpath("//*[@class='select2-results__option']"));

    for(int i = 1; i < elm.size(); i++) 
    {   
            By ID = By.id(driver.findElements(By.xpath("//*[@class='select2-results__option']")).get(i).getText());
            System.out.println(ID);         

            driver.findElements(By.xpath("//*[@class='select2-results__option']")).get(i).click();
            Thread.sleep(500);
    } 
}

在城市“ADANA”之后出现 java.lang.IndexOutOfBoundsException: Index: 2, Size: 0 错误。 如果我设法处理第一个错误,我将编写第二个和第三个 for 循环,所以现在的代码是这样的。

当问题解决后,我想首先获得所有城市。然后是每个城市的县。然后是每个县的站点。这必须根据城市列表、县列表和站点列表的大小动态完成。为此,我需要三个嵌套的 for 循环。毕竟,每个值都必须写在excel中。

【问题讨论】:

    标签: java selenium-webdriver selenium-chromedriver


    【解决方案1】:

    这是对我有用的代码

     public void testMethod() {
        driver.manage().window().maximize();
    
        WebElement firstDropDown = driver.findElement(By.id("select2-city-list-container"));
        firstDropDown.click();
        sleep();
        List<WebElement> citiesEls = getCitiesEls();
        Map<String, Map<String, List<String>>> cityData = new HashMap<>();
        for (int i = 0; i < citiesEls.size(); i++) {
            //we need to take this element every iteration, because it gets reloaded every time we open the dropdown
            WebElement cityEl = driver.findElement(By.id("select2-city-list-results")).findElements(By.xpath("//*[contains(@id,'select2-city-list-result')]")).get(i);
            String cityText = cityEl.getText();
            cityEl.click();
            sleep();
    
            cityData.put(cityText, getRegions());
    
            firstDropDown.click();
            sleep();
        }
    
        System.out.println(cityData);
    }
    
    private Map<String, List<String>> getRegions() {
        WebElement secondDropDown = driver.findElement(By.id("select2-region-list-container"));
        secondDropDown.click();
        sleep();
        List<WebElement> regionsEls = getRegionEls();
        Map<String, List<String>> regionData = new HashMap<>();
        for (int i = 0; i < regionsEls.size(); i++) {
            WebElement regionEl = driver.findElement(By.id("select2-region-list-results")).findElements(By.xpath("//*[contains(@id,'select2-region-list-result')]")).get(i);
            String regionText = regionEl.getText();
            regionEl.click();
            WebElement thirdDropDown = driver.findElement(By.id("select2-site-list-container"));
            thirdDropDown.click();
            List<WebElement> sitesEl = getSiteEls();
            List<String> sitesTexts = getSites(sitesEl);
            //populate region data
            regionData.put(regionText, sitesTexts);
    
            secondDropDown.click();
            sleep();
        }
        return regionData;
    }
    
    private List<String> getSites(List<WebElement> sitesEl) {
        List<String> sitesTexts = new ArrayList<>();
        for (WebElement siteEl : sitesEl) {
            sitesTexts.add(siteEl.getText());
        }
        return sitesTexts;
    }
    
    private List<WebElement> getSiteEls() {
        WebElement ulSites = driver.findElement(By.id("select2-site-list-results"));
        return ulSites.findElements(By.xpath("//*[contains(@id,'select2-site-list-result')]"));
    }
    
    private List<WebElement> getRegionEls() {
        return driver.findElement(By.id("select2-region-list-results")).findElements(By.xpath("//*[contains(@id,'select2-region-list-result')]"));
    }
    
    private List<WebElement> getCitiesEls() {
        return driver.findElement(By.id("select2-city-list-results")).findElements(By.xpath("//*[contains(@id,'select2-city-list-result')]"));
    }
    

    由于每次点击后数据都会动态更改,因此每次点击后您可能需要一些延迟。下面的代码在 Mac+Chrome 上运行良好。不过,如果您最终失败,请在每次点击后添加一个 sleep 方法调用。

      private void sleep() {
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              throw new IllegalStateException(e);
          }
        }
    

    重要提示:不建议使用 Sleeps,仅应将其用作快速的临时解决方法。更健壮的解决方案是使用smart waits

    【讨论】:

    • 谢谢。我知道等待是的,但这是一次性项目,优化不是强制性的。还有在哪里添加for循环?据我所知,我需要三个嵌套的 for 循环。
    • 在这种情况下定义你需要循环做什么?循环是您想要重复执行某些操作的必要条件。我想你需要清楚地解释你正在尝试解决的任务——那么添加循环就没有问题了;)
    • 是的,我没有说对不起。我想首先获得所有城市。然后是每个城市的县。然后是每个县的站点。这必须根据城市列表、县列表和站点列表的大小动态完成。为此,我需要三个嵌套的 for 循环。毕竟,每个值都必须写在excel中。感谢您的努力。
    • @GunesK 用似乎有效的代码更新了答案。我没有等到最后,但它看起来像预期的那样工作,请从你的最后检查它并在必要时进行调试。
    • 在cityData中应该有城市---地区---城市的完整数据。主地图中的键是城市,值是第二张地图,其中键是区域,值是区域的站点列表
    猜你喜欢
    • 2017-12-16
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多