如何在我的java应用程序中使用selenium单击下拉菜单中的按钮?

问题描述 投票:0回答:3

我需要从网站读取数据并基于此数据构建菜单对象。

但在执行此操作之前,我需要使用该网站的英文版本,然后单击右上角的语言更改按钮。问题是语言更改按钮并不总是被点击,出现以下异常:

org.openqa.selenium.NoSuchElementException:没有这样的元素:无法定位元素:{“method”:“css选择器”,“selector”:“.lang-list .lang-list-item:nth-child(2) “}

这是我的代码:

  1. 因按钮不常按下而出现问题的方法:

    private void changeLanguage(WebDriver driver) {
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        WebElement languageMenu = wait.until(ExpectedConditions.elementToBeClickable(By.className("menu-switcher")));
        languageMenu.click();
        wait.until(ExpectedConditions.presenceOfElementLocated((By.cssSelector(".lang-list .lang-list-item:nth-child(2)"))));
        WebElement enLanguage = driver.findElement(By.cssSelector(".lang-list .lang-list-item:nth-child(2)"));
        enLanguage.click();
    }
    
  2. 接下来,您将找到构建菜单、获取所有类别的链接以及构建类别的方法:

     private Menu crawlExpirenza(WebDriver driver, String url) {
        driver.get(url);
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
        WebElement info = wait.until(ExpectedConditions.presenceOfElementLocated(By.className("info-wrapper")));
        WebElement placeName = info.findElement(By.className("title"));
        Menu.MenuBuilder menuBuilder = Menu.builder();
        menuBuilder.placeName(placeName.getText());
    
        Map<String, String> allCategoriesLinks = getAllCategories(driver, wait);
        List<Category> categories = new ArrayList<>();
        for (String link : allCategoriesLinks.keySet()) {
            Category category = buildExpirenzaCategory(link, driver, wait, allCategoriesLinks);
            categories.add(category);
        }
        menuBuilder.categories(categories);
        return menuBuilder.build();
    }
    
    private Map<String, String> getAllCategories(WebDriver driver, WebDriverWait wait) {
        Map<String, String> allCategories = new HashMap<>();
        changeLanguage(driver);
        List<WebElement> sideMenuCategories = wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.className("category__link")));
    
        for (WebElement sideMenuCategory : sideMenuCategories) {
            String href = sideMenuCategory.getAttribute("href");
            String name = sideMenuCategory.getText();
            allCategories.put(href, name);
        }
        return allCategories;
    }
    
    private Category buildExpirenzaCategory(String link, WebDriver driver, WebDriverWait wait, Map<String, String> allCategories) {
        driver.navigate().to(link);
        changeLanguage(driver);
        Category.CategoryBuilder categoryBuilder = Category.builder();
        categoryBuilder.name(allCategories.get(link));
        List<Dish> dishes = buildExpirenzaDishes(wait);
        categoryBuilder.dishes(dishes);
        return categoryBuilder.build();
    }
    

请帮助我修复

changeLanguage()
方法,以便正确单击链接上的按钮,并使其适用于每个类别(芝士蛋糕和其他甜点、面包店、咖啡和其他饮料、柠檬水、滋补品等) 、起泡鸡尾酒、有机和无酒精葡萄酒、啤酒、礼品和其他东西 - 所有这些类别都有不同的链接)

我尝试使用其他网络驱动程序和网站的移动版本,但按钮仍然只有一半的时间被点击。

java spring selenium-webdriver web-crawler
3个回答
0
投票

你可以试试这个吗?

wait = WebDriverWait(driver, 10)
body = wait.until(EC.presence_of_element_located((By.TAG_NAME, "body")))
wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "menu-switcher")))
language_menu = driver.find_element(By.CLASS_NAME, "menu-switcher")
language_menu.click()
print('clicked language menu')
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".lang-list .lang-list-item:nth-child(2)")))
en_language = driver.find_element(By.CSS_SELECTOR, ".lang-list .lang-list-item:nth-child(2)")
en_language.click()

我用 python 做了这个及其工作:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
url = 'https://expz.menu/468539b8-d84b-42fa-b57c-6706d62b9acc/menu?menuId=585'
driver.get(url)
wait = WebDriverWait(driver, 10)
body = wait.until(EC.presence_of_element_located((By.TAG_NAME, "body")))
wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "menu-switcher")))
language_menu = driver.find_element(By.CLASS_NAME, "menu-switcher")
language_menu.click()
print('clicked language menu')
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".lang-list .lang-list-item:nth-child(2)")))
en_language = driver.find_element(By.CSS_SELECTOR, ".lang-list .lang-list-item:nth-child(2)")
en_language.click()

0
投票

该页面上发生了一些非常奇怪的事情。由于某种原因,当页面首次加载时,所有常见的

WebDriverWait
类型都不起作用。我尝试了存在、可见和可点击,但它们都超时了。我什至尝试等待陈旧的想法,认为页面加载然后重新加载(即使我没有看到页面闪烁),但这不起作用。我发现唯一有效的就是添加一个
Thread.sleep()
。这通常是一种不好的做法,但是当您有一个像这个网站一样行为不当的网站时,我找不到更好的选择。

我还更改了“EN”菜单项的定位器以使其更清晰等

下面的代码对我来说一直有效。

private void changeLanguage(WebDriver driver) throws InterruptedException {
    Thread.sleep(5000);
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
    wait.until(ExpectedConditions.elementToBeClickable(By.className("menu-switcher"))).click();
    wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//ul[@class='lang-list']/li[text()='EN']"))).click();
}

-1
投票

这里为您准备了三件事。

  1. 通过检查确保定位器正确。

  2. 导航到页面后尝试给予 Thread.Sleep(3000),这将暂停执行并查找元素,如果此工作则使用等待,因为不建议使用线程。

  3. 尝试使用selenium提供的Select类。下面是它的代码:

    WebElement selectElement = driver.findElement(By.id("select_id"));
    Select dropdown= new Select(selectElement);
    // Select option by visible text
    dropdown.selectByVisibleText("Option");
    // Select option by value
    dropdown.selectByValue("value");
    // Select option by index
    dropdown.selectByIndex(1);
    
© www.soinside.com 2019 - 2024. All rights reserved.