我需要从网站读取数据并基于此数据构建菜单对象。
但在执行此操作之前,我需要使用该网站的英文版本,然后单击右上角的语言更改按钮。问题是语言更改按钮并不总是被点击,出现以下异常:
org.openqa.selenium.NoSuchElementException:没有这样的元素:无法定位元素:{“method”:“css选择器”,“selector”:“.lang-list .lang-list-item:nth-child(2) “}
这是我的代码:
因按钮不常按下而出现问题的方法:
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();
}
接下来,您将找到构建菜单、获取所有类别的链接以及构建类别的方法:
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()
方法,以便正确单击链接上的按钮,并使其适用于每个类别(芝士蛋糕和其他甜点、面包店、咖啡和其他饮料、柠檬水、滋补品等) 、起泡鸡尾酒、有机和无酒精葡萄酒、啤酒、礼品和其他东西 - 所有这些类别都有不同的链接)
我尝试使用其他网络驱动程序和网站的移动版本,但按钮仍然只有一半的时间被点击。
你可以试试这个吗?
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()
该页面上发生了一些非常奇怪的事情。由于某种原因,当页面首次加载时,所有常见的
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();
}
这里为您准备了三件事。
通过检查确保定位器正确。
导航到页面后尝试给予 Thread.Sleep(3000),这将暂停执行并查找元素,如果此工作则使用等待,因为不建议使用线程。
尝试使用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);