Link 在使用 selenium 进行网页自动化期间无法打开
Link not opening during web page automation with selenium
我一直在尝试通过 selenium 自动执行浏览器操作,目标是 - google.com
将被打开,gmail
文本将被搜索,第一个 link 将被点击并打开。使用的代码是--
public static void main(String[] args) {
WebDriver driver= new FirefoxDriver();
driver.get("https://www.google.co.in");
driver.manage().window().maximize();
WebElement searchbox= driver.findElement(By.id("lst-ib"));
searchbox.sendKeys("gmail");
driver.findElement(By.name("btnG")).click();
driver.findElement(By.xpath("//ol[@id='rso']//div[1]//div[1]//div//h3//a")).click();
}
但什么也没发生,我收到一个错误 -
error-Exception in thread "main"
org.openqa.selenium.NoSuchElementException: Unable to locate element:
{"method":"xpath","selector":"//ol[@id='rso']//div[1]//div[1]//div//h3//a"}
我哪里做错了?
您收到错误消息是因为您试图在第一个 link (gmail) 加载之前点击它。更新您的代码以实现 wait
直到元素在您搜索内容并单击搜索按钮后加载。 Selenium 中有许多类型的 wait
可用,使用显式等待在两个操作之间等待,这是我最喜欢的方法。方法如下 -
driver.findElement(By.name("btnG")).click();
(new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//ol[@id='rso']//div[1]//div[1]//div//h3//a"))).click(); //explicitly wait for the element to load and then click
另一种更好的处理方法是等待元素出现,如果元素出现则使用 Fluent 等待继续轮询页面。方法如下 -
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class); //create a fluent wait object
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//ol[@id='rso']//div[1]//div[1]//div//h3//a"))).click(); //fluent wait until element loads
您也可以使用隐式等待时间。在 selenium 执行的每个操作之后等待预定义的时间。但这又是一个不可取的方法,因为它有时会在网页性能缓慢时抛出错误。方法如下 -
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); //implicitly wait until element loads for predefined time
driver.get("https://www.google.co.in");
但是,解决您问题的最简单方法是使用简单的 sleep()
方法,我不喜欢 使用 sleep()
方法。我不喜欢它是因为它有时会在元素加载时间较长时抛出错误,因为 selenium 会等待您指定的预定义时间,这是一个糟糕的编码标准。方法如下 -
driver.findElement(By.name("btnG")).click();
Thread.sleep(5000); //Use sleep() method to wait for a predefined time
driver.findElement(By.xpath("//ol[@id='rso']//div[1]//div[1]//div//h3//a")).click();
希望对您有所帮助。
我看到我的动态 ID 已被使用,不建议使用动态 ID[因为它会不断变化],同时使用必要的等待条件来避免此类异常
driver.findElement(By.id("lst-ib")); //lst-ib is dynamic value.
我尝试复制您的场景,没有发现任何问题,请在下面找到编码,
package testclasses;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Action;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.*;
import org.testng.annotations.*;
public class classa extends classparent {
@Test
public void methoda() throws InterruptedException {
driver.manage().window().maximize();
driver.get("https://www.google.co.in/");
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(text(),'Gmail')]")));
WebElement close = driver.findElement(By.xpath("//a[contains(text(),'Gmail')]"));
if(close.isDisplayed()){
System.out.println("element is visible " +close);
close.click();
}
else{
System.out.println("element is not visible " +close);
}
}
}
控制台输出,
TestNG] Running:
C:\Users\Mohan Raj S\AppData\Local\Temp\testng-eclipse-1635948262\testng-customsuite.xml
element is visible [[FirefoxDriver: firefox on WINDOWS (6d5bc9d3-cdff-4831-991a-69d7d7ce3d36)] -> xpath: //a[contains(text(),'Gmail')]]
PASSED: methoda
===============================================
Default test
Tests run: 1, Failures: 0, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================
您代码中的以下 Xpath 格式错误:
driver.findElement(By.xpath("//ol[@id='rso']//div[1]//div[1]//div//h3//a")).click();
请使用以下 Xpath 将完美运行。
WebDriver driver= new FirefoxDriver();
driver.get("https://www.google.co.in");
driver.manage().window().maximize();
WebElement searchbox= driver.findElement(By.id("lst-ib"));
searchbox.sendKeys("gmail");
driver.findElement(By.name("btnG")).click();
driver.findElement(By.xpath("//ol[@id='rso']/div[1]/div[1]/div/h3/a")).click();
我修改的Xpath是。
driver.findElement(By.xpath("//ol[@id='rso']/div[1]/div[1]/div/h3/a")).click();
我一直在尝试通过 selenium 自动执行浏览器操作,目标是 - google.com
将被打开,gmail
文本将被搜索,第一个 link 将被点击并打开。使用的代码是--
public static void main(String[] args) {
WebDriver driver= new FirefoxDriver();
driver.get("https://www.google.co.in");
driver.manage().window().maximize();
WebElement searchbox= driver.findElement(By.id("lst-ib"));
searchbox.sendKeys("gmail");
driver.findElement(By.name("btnG")).click();
driver.findElement(By.xpath("//ol[@id='rso']//div[1]//div[1]//div//h3//a")).click();
}
但什么也没发生,我收到一个错误 -
error-Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"xpath","selector":"//ol[@id='rso']//div[1]//div[1]//div//h3//a"}
我哪里做错了?
您收到错误消息是因为您试图在第一个 link (gmail) 加载之前点击它。更新您的代码以实现 wait
直到元素在您搜索内容并单击搜索按钮后加载。 Selenium 中有许多类型的 wait
可用,使用显式等待在两个操作之间等待,这是我最喜欢的方法。方法如下 -
driver.findElement(By.name("btnG")).click();
(new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//ol[@id='rso']//div[1]//div[1]//div//h3//a"))).click(); //explicitly wait for the element to load and then click
另一种更好的处理方法是等待元素出现,如果元素出现则使用 Fluent 等待继续轮询页面。方法如下 -
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class); //create a fluent wait object
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//ol[@id='rso']//div[1]//div[1]//div//h3//a"))).click(); //fluent wait until element loads
您也可以使用隐式等待时间。在 selenium 执行的每个操作之后等待预定义的时间。但这又是一个不可取的方法,因为它有时会在网页性能缓慢时抛出错误。方法如下 -
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); //implicitly wait until element loads for predefined time
driver.get("https://www.google.co.in");
但是,解决您问题的最简单方法是使用简单的 sleep()
方法,我不喜欢 使用 sleep()
方法。我不喜欢它是因为它有时会在元素加载时间较长时抛出错误,因为 selenium 会等待您指定的预定义时间,这是一个糟糕的编码标准。方法如下 -
driver.findElement(By.name("btnG")).click();
Thread.sleep(5000); //Use sleep() method to wait for a predefined time
driver.findElement(By.xpath("//ol[@id='rso']//div[1]//div[1]//div//h3//a")).click();
希望对您有所帮助。
我看到我的动态 ID 已被使用,不建议使用动态 ID[因为它会不断变化],同时使用必要的等待条件来避免此类异常
driver.findElement(By.id("lst-ib")); //lst-ib is dynamic value.
我尝试复制您的场景,没有发现任何问题,请在下面找到编码,
package testclasses;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Action;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.*;
import org.testng.annotations.*;
public class classa extends classparent {
@Test
public void methoda() throws InterruptedException {
driver.manage().window().maximize();
driver.get("https://www.google.co.in/");
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(text(),'Gmail')]")));
WebElement close = driver.findElement(By.xpath("//a[contains(text(),'Gmail')]"));
if(close.isDisplayed()){
System.out.println("element is visible " +close);
close.click();
}
else{
System.out.println("element is not visible " +close);
}
}
}
控制台输出,
TestNG] Running:
C:\Users\Mohan Raj S\AppData\Local\Temp\testng-eclipse-1635948262\testng-customsuite.xml
element is visible [[FirefoxDriver: firefox on WINDOWS (6d5bc9d3-cdff-4831-991a-69d7d7ce3d36)] -> xpath: //a[contains(text(),'Gmail')]]
PASSED: methoda
===============================================
Default test
Tests run: 1, Failures: 0, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================
您代码中的以下 Xpath 格式错误:
driver.findElement(By.xpath("//ol[@id='rso']//div[1]//div[1]//div//h3//a")).click();
请使用以下 Xpath 将完美运行。
WebDriver driver= new FirefoxDriver();
driver.get("https://www.google.co.in");
driver.manage().window().maximize();
WebElement searchbox= driver.findElement(By.id("lst-ib"));
searchbox.sendKeys("gmail");
driver.findElement(By.name("btnG")).click();
driver.findElement(By.xpath("//ol[@id='rso']/div[1]/div[1]/div/h3/a")).click();
我修改的Xpath是。
driver.findElement(By.xpath("//ol[@id='rso']/div[1]/div[1]/div/h3/a")).click();