我对Selenium还不熟悉。
为了学习更多关于selenium的知识,我开始使用Java语言中的Selenium web驱动程序自动化网站"https://www.findmyfare.com/“的航班搜索流程。
我可以点击搜索按钮。但它会指向一个错误页面,而不是根据我的搜索条件生成结果。
当我手动执行搜索时,它工作得很好。
有人能帮我解决这个问题吗?
注意:此搜索按钮不是“提交”类型。因此,我使用click()方法。(我也尝试了submit(),也没有区别)。
以下是触发搜索的代码段。
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.Test;
public class FlightSearchWD
{
public WebDriver driver = null;
public String baseUrl;
@Test
public void testFlightSearchWD()
{
driver = new FirefoxDriver();
driver.get("https://www.findmyfare.com/");
driver.findElement(By.id("from_1")).click();
WebElement cleartext = driver.findElement(By.id("from_1"));
cleartext.clear();
WebElement FromCity = driver.findElement(By.id("from_1"));
FromCity.sendKeys("Auckland, New Zealand (AKL)");
driver.findElement(By.id("to_1")).click();
WebElement cleartext1 = driver.findElement(By.id("to_1"));
cleartext1.clear();
WebElement ToCity = driver.findElement(By.id("to_1"));
ToCity.sendKeys("Colombo, Sri Lanka (CMB)");
WebElement FromDate = driver.findElement(By.id("date_1"));
FromDate.click();
WebElement datepicker = driver.findElement(By.id("ui-datepicker-div"));
List<WebElement> rows = datepicker.findElements(By.tagName("tr"));
List<WebElement> columns = datepicker.findElements(By.tagName("td"));
for (WebElement cell : columns)
{
// Select 20th Date
if (cell.getText().equals("20"))
{
cell.findElement(By.linkText("20")).click();
break;
}
}
// select to date
WebElement ToDate = driver.findElement(By.id("date_2"));
ToDate.click();
WebElement datepicker2 = driver.findElement(By.id("ui-datepicker-div"));
List<WebElement> rows1 = datepicker2.findElements(By.tagName("tr"));
List<WebElement> columns1 = datepicker2.findElements(By.tagName("td"));
for (WebElement cell1 : columns1)
{
// Select 20th Date
if (cell1.getText().equals("25"))
{
cell1.findElement(By.linkText("25")).click();
break;
}
}
WebElement ClickTravellers = driver.findElement(By.id("PopS"));
ClickTravellers.click();
addAdults();
addChildren();
addInfant();
WebElement clickSearch = driver.findElement(By.id("search_flight_submit"));
clickSearch.click();
}
private void addAdults()
{
while (true)
{
WebElement popOverBtnGrp = driver
.findElement(By.xpath("//div[@class='btn-group col-xs-12 col-md-12 col-sm-12']"));
if (popOverBtnGrp.isDisplayed())
{
try
{
WebElement NoOfTravellers = driver.findElement(By.xpath(
"//button[@class='btn add_people ripple-effect btn-default btn-sm col-xs-2 col-md-4 col-sm-4']"));
for (int i = 0; i < 1; i++)
{
NoOfTravellers.click();
}
break;
} catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
private void addChildren()
{
while (true)
{
WebElement popOverBtnGrp = driver
.findElement(By.xpath("//div[@class='btn-group col-xs-12 col-md-12 col-sm-12']"));
if (popOverBtnGrp.isDisplayed())
{
try
{
WebElement NoOfTravellers = driver.findElement(By.xpath("//button[@class=' add_people btn btn-default btn-sm ripple-effect col-xs-2 col-md-4 col-sm-4' and @data-id='childrens']"));
for (int i = 0; i < 1; i++)
{
NoOfTravellers.click();
}
break;
} catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
private void addInfant()
{
while (true)
{
WebElement popOverBtnGrp = driver
.findElement(By.xpath("//div[@class='btn-group col-xs-12 col-md-12 col-sm-12']"));
if (popOverBtnGrp.isDisplayed())
{
try
{
WebElement NoOfTravellers = driver.findElement(By.xpath("//button[@class='add_people btn btn-default btn-sm ripple-effect col-xs-2 col-md-4 col-sm-4' and @data-id='infants']"));
for (int i = 0; i < 1; i++)
{
NoOfTravellers.click();
}
break;
} catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}发布于 2016-08-08 02:26:33
感谢@Asha,我也是selenium webdriver的新手,从这个查询中学到了很多,最终找到了解决方案。
import java.util.List;
import org.testng.annotations.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class FlightSearchWD {
public WebDriver driver = null;
public String baseUrl;
@Test
public void testFlightSearchWD() throws InterruptedException {
driver = new FirefoxDriver();
driver.get("https://www.findmyfare.com/");
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement from1 = wait.until(ExpectedConditions
.presenceOfElementLocated(By.id("from_1")));
from1.click();
from1.clear();
from1.sendKeys("AKL");
from1.sendKeys(Keys.ENTER);
driver.findElement(By.id("to_1")).click();
WebElement cleartext1 = driver.findElement(By.id("to_1"));
cleartext1.clear();
WebElement ToCity = driver.findElement(By.id("to_1"));
ToCity.sendKeys("CMB");
ToCity.sendKeys(Keys.ENTER);
Thread.sleep(3000);
driver.findElement(By.xpath(".//*[@id='trip_types']")).click();
driver.findElement(By.id("date_1")).click();
List<WebElement> total_date = driver
.findElements(By
.xpath("//div[@class='panel-body']/div[@class='pull-left col-md-6 pull-left-first']/table[1]//td"));
int total_date_size = total_date.size();
for (int i = 0; i < total_date_size; i++) {
String date = total_date.get(i).getText();
if (date.equalsIgnoreCase("20")) {
total_date.get(i).click();
break;
}
}
driver.findElement(By.id("date_2")).click();
List<WebElement> total_date1 = driver
.findElements(By
.xpath("//div[@class='panel-body']/div[@class='pull-left col-md-6 pull-left-first']/table[1]//td"));
int total_date_size1 = total_date1.size();
for (int i = 0; i < total_date_size1; i++) {
String date1 = total_date1.get(i).getText();
if (date1.equalsIgnoreCase("25")) {
total_date1.get(i).click();
break;
}
}
WebElement ClickTravellers = driver.findElement(By.id("PopS"));
ClickTravellers.click();
addAdults();
addChildren();
addInfant();
WebElement clickSearch = driver.findElement(By
.id("search_flight_submit"));
clickSearch.click();
}
private void addAdults() {
while (true) {
WebElement popOverBtnGrp = driver
.findElement(By
.xpath("//div[@class='btn-group col-xs-12 col-md-12 col-sm-12']"));
if (popOverBtnGrp.isDisplayed()) {
try {
WebElement NoOfTravellers = driver
.findElement(By
.xpath("//button[@class='btn add_people ripple-effect btn-default btn-sm col-xs-2 col-md-4 col-sm-4']"));
for (int i = 0; i < 1; i++) {
NoOfTravellers.click();
}
break;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
private void addChildren() {
while (true) {
WebElement popOverBtnGrp = driver
.findElement(By
.xpath("//div[@class='btn-group col-xs-12 col-md-12 col-sm-12']"));
if (popOverBtnGrp.isDisplayed()) {
try {
WebElement NoOfTravellers = driver
.findElement(By
.xpath("//button[@class=' add_people btn btn-default btn-sm ripple-effect col-xs-2 col-md-4 col-sm-4' and @data-id='childrens']"));
for (int i = 0; i < 1; i++) {
NoOfTravellers.click();
}
break;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
private void addInfant() {
while (true) {
WebElement popOverBtnGrp = driver
.findElement(By
.xpath("//div[@class='btn-group col-xs-12 col-md-12 col-sm-12']"));
if (popOverBtnGrp.isDisplayed()) {
try {
WebElement NoOfTravellers = driver
.findElement(By
.xpath("//button[@class='add_people btn btn-default btn-sm ripple-effect col-xs-2 col-md-4 col-sm-4' and @data-id='infants']"));
for (int i = 0; i < 1; i++) {
NoOfTravellers.click();
}
break;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}如果您对此有任何问题,请让我知道。
发布于 2016-08-07 23:19:05
Selenium非常适合在浏览器中模拟用户交互。但是,默认情况下,这些命令遵循一个简单的顺序。您在驱动程序中加载一个页面。一旦页面“完成”加载,它就会立即执行您告诉它的操作。如果您说find an element,它会遍历DOM,试图找到与By定位器匹配的元素。如果它找到一个,就会返回它。如果没有找到,就会抛出异常。虽然对于selenium项目或非常静态的网站来说,这是一个很好的默认设置,但现在的网站更多的是动态的。页面将被认为是“加载的”,但大多数内容是通过异步调用获取的。这是因为它给用户一种页面“时髦”的感觉,因为它允许与“折叠之上”的部分或关键内容进行交互,而不是让他们等待他们可能不关心的部分。不幸的是,这使得现代网站的自动化变得更加困难。通常,在非静态网站上使用Selenium时,最好使用WebDriverWait包装所有交互,以确保元素在尝试单击之前处于您期望的状态。下面是一个等待条件的简单例子。
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class FooTest {
@Test
public void foo() {
WebDriver driver = new FirefoxDriver();
driver.get("https://www.findmyfare.com/");
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.id("from_1")))
.click();
// ... etc
driver.quit();
}
}请注意,上面web驱动程序等待的构造函数中的数字"10“是以秒为单位的超时。如果在10秒内没有找到具有匹配id的元素处于可点击状态,则会抛出异常。
发布于 2016-08-08 02:25:30
其他人说的对,在你的元素调用中应该有等待。您已经设法通过执行while循环解决了这个问题,但是等待几乎总是更好。我下载了您的代码并运行了它,您面临的问题实际上与selenium没有直接关系。
所以,您提到不是转到结果页面,而是转到错误页面,我认为从网站的角度来看,这是预期的行为。我最好的猜测是,他们可以检测到浏览他们网站的“用户”是否是“机器人”,如果是“机器人”,则转到不同的页面,而不是常规的搜索结果页面。尝试另一个网站来测试您的selenium脚本,我非常确定它是有效的。
无论如何,我已经创建了一个面向初学者的selenium框架,并帮助您避免这里提到的问题。一旦你的测试完成,它甚至会自动关闭浏览器。下面是使用easytest框架对上面的代码进行的翻译。
@Test
public void testFindMyFare() throws Exception {
try(EasyTest easy = new EasyTest(DriverType.CHROME)) {
// start
easy.start("https://www.findmyfare.com/");
// homepage
easy.newPage(page -> {
page.typeText("#from_1", "Auckland, New Zealand (AKL)");
page.typeText("#to_1", "Colombo, Sri Lanka (CMB)");
// click from date slector and select 20th
page.click("#date_1");
page.executeIn("#ui-datepicker-div", container -> {
container.click(":20");
});
// click to date slector and select 25th
page.click("#date_2");
page.executeIn("#ui-datepicker-div", container -> {
container.click(":25");
});
// click travellers
page.click("#PopS");
// add people
page.executeIn(".popover", container -> {
container.click("button[data-id='adults'].add_people");
container.click("button[data-id='childrens'].add_people");
container.click("button[data-id='infants'].add_people");
});
// click find flight button
page.clickButton("#search_flight_submit");
});
}
}如果你觉得上面的测试更容易阅读和遵循,你可以在https://github.com/codezombies/easytest下载easytest框架。如果我能帮助你学习selenium,请告诉我。
https://stackoverflow.com/questions/38813149
复制相似问题