如何处理在网页上没有任何结果的搜索?

时间:2018-07-03 05:07:13

标签: java selenium selenium-webdriver

几天前,我在其他一些Stack Overflow成员的帮助下编写了一个程序,现在我遇到了一个新的功能问题。

这是我的代码:

// importing a bunch of packages

public class webSearch  {
public webSearch() {

}

public WebDriver driver = new ChromeDriver();

public void openTestSite() {
    //driver.navigate().to(the URL for the website);
    driver.get("https://wonef.fr/try/");
    driver.manage().window().maximize();
    //Explicit wait is added after the Page load
    WebDriverWait wait=new WebDriverWait(driver,20);
    wait.until(ExpectedConditions.titleContains("WoNeF"));
} 

public void enter(String word) {

    WebElement query_editbox =
            driver.findElement(By.id("query"));
    query_editbox.sendKeys(word);
    //AutoComplete is happening even after sending the Enter Key.
    // So, Value needs to be selected from the autocomplete
    WebDriverWait wait=new WebDriverWait(driver,20);
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@class='autocomplete']/div")));
    List<WebElement> matchedList=driver.findElements(By.xpath("//div[@class='autocomplete']/div"));

   // System.out.println(matchedList.size());
    for(WebElement element : matchedList){
        if(element.getText().equalsIgnoreCase(word)){
            element.click();
        }
    }
    query_editbox.sendKeys(Keys.RETURN);
}

public void getText(String name) throws IOException  {
    WebDriverWait wait=new WebDriverWait(driver,20);
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@id='mid']/div")));
    WebElement result=driver.findElement(By.id("mid"));
    Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(name), "utf-8"));
    writer.write(result.getText());
    writer.close();
}

}

它基本上会打开一个网站,输入一个单词,按Enter,然后将返回的内容保存到文本文件中。

我的问题是,当输入一个单词但搜索没有一个命中时,如何处理该程序。这总是在我的代码中导致以下错误:

Exception in thread "main" org.openqa.selenium.TimeoutException: Expected condition failed: waiting for visibility of element located by By.xpath: //div[@class='autocomplete']/div (tried for 20 second(s) with 500 milliseconds interval)
    at org.openqa.selenium.support.ui.WebDriverWait.timeoutException(WebDriverWait.java:81)
    at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:271)
    at src.webSearch.enter(webSearch.java:43)
    at src.Engine.main(Engine.java:58)
Caused by: org.openqa.selenium.NoSuchElementException: Cannot locate an element using By.xpath: //div[@class='autocomplete']/div
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '3.13.0', revision: '2f0d292', time: '2018-06-25T15:32:14.902Z'
System info: host: 'my-MacBook-Air.local', ip: 'fe80:0:0:0:a6d1:8cff:fece:5dae%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.11.6', java.version: '1.8.0_171'
Driver info: driver.version: unknown
    at org.openqa.selenium.support.ui.ExpectedConditions.lambda$findElement$0(ExpectedConditions.java:896)
    at java.util.Optional.orElseThrow(Optional.java:290)
    at org.openqa.selenium.support.ui.ExpectedConditions.findElement(ExpectedConditions.java:895)
    at org.openqa.selenium.support.ui.ExpectedConditions.access$000(ExpectedConditions.java:44)
    at org.openqa.selenium.support.ui.ExpectedConditions$7.apply(ExpectedConditions.java:206)
    at org.openqa.selenium.support.ui.ExpectedConditions$7.apply(ExpectedConditions.java:202)
    at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:248)
... 2 more

新错误:

Exception in thread "main" org.openqa.selenium.TimeoutException: Expected condition failed: waiting for visibility of element located by By.xpath: //div[@id='mid']/div (tried for 20 second(s) with 500 milliseconds interval)
    at org.openqa.selenium.support.ui.WebDriverWait.timeoutException(WebDriverWait.java:81)
    at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:271)
    at src.webSearch.getText(webSearch.java:62)
    at src.Engine.main(Engine.java:57)
Caused by: org.openqa.selenium.NoSuchElementException: Cannot locate an element using By.xpath: //div[@id='mid']/div
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '3.13.0', revision: '2f0d292', time: '2018-06-25T15:32:14.902Z'
System info: host: 'my-MacBook-Air.local', ip: 'fe80:0:0:0:a6d1:8cff:fece:5dae%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.11.6', java.version: '1.8.0_171'
Driver info: driver.version: unknown
    at org.openqa.selenium.support.ui.ExpectedConditions.lambda$findElement$0(ExpectedConditions.java:896)
    at java.util.Optional.orElseThrow(Optional.java:290)
    at org.openqa.selenium.support.ui.ExpectedConditions.findElement(ExpectedConditions.java:895)
    at org.openqa.selenium.support.ui.ExpectedConditions.access$000(ExpectedConditions.java:44)
    at org.openqa.selenium.support.ui.ExpectedConditions$7.apply(ExpectedConditions.java:206)
    at org.openqa.selenium.support.ui.ExpectedConditions$7.apply(ExpectedConditions.java:202)
    at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:248)
    ... 2 more

新编辑! 他是我很久以前的代码。

import java.io.BufferedWriter;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.lang.ClassLoader;

import com.sun.corba.se.impl.orbutil.threadpool.TimeoutException;



public class webSearch  {

    public webSearch() {

    }

    public WebDriver driver = new ChromeDriver()
            ;

    public void openTestSite() {

    //driver.navigate().to(the URL for the website);
    driver.get("https://wonef.fr/try/");
    driver.manage().window().maximize();
    //Explicit wait is added after the Page load
    WebDriverWait wait=new WebDriverWait(driver,20);
    wait.until(ExpectedConditions.titleContains("WoNeF"));
}


    public void enter(String word) {

        WebElement query_editbox =
                driver.findElement(By.id("query"));
        System.out.println("Hello");
        query_editbox.sendKeys(word);
        System.out.println("Hello");
        //AutoComplete is happening even after sending the Enter Key.
        // So, Value needs to be selected from the autocomplete
        WebDriverWait wait=new WebDriverWait(driver,20);
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@class='autocomplete']/div")));
        List<WebElement> matchedList=driver.findElements(By.xpath("//div[@class='autocomplete']/div"));

        System.out.println(matchedList.size());
        for(WebElement element : matchedList){
            if(element.getText().equalsIgnoreCase(word)){
                element.click();
            }
        }
        //query_editbox.sendKeys(Keys.RETURN);
    }

    public void getText()  {
        WebDriverWait wait=new WebDriverWait(driver,20);
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@id='mid']/div")));
        WebElement result=driver.findElement(By.id("mid"));
        System.out.println(result.getText());
    }

    public static void main(String[] args) {
        System.setProperty("webdriver.chrome.driver", "/Users/shivamsinghal/Documents/chromedriver.exe");        
        System.out.println("Hello");

        webSearch webSrcapper = new webSearch();
        webSrcapper.openTestSite();
        webSrcapper.enter("avoir");
        webSrcapper.getText();
        System.out.println("Hello");
    }
}

以下是我收到的新错误:

Command duration or timeout: 0 milliseconds
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:25:48'
System info: host: 'ny-MacBook-Air.local', ip: 'fe80:0:0:0:a6d1:8cff:fece:5dae%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.11.6', java.version: '1.8.0_171'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, acceptSslCerts: false, applicationCacheEnabled: false, browserConnectionEnabled: false, browserName: chrome, chrome: {chromedriverVersion: 2.40.565386 (45a059dc425e08..., userDataDir: /var/folders/pq/hvxfhc1s22x...}, cssSelectorsEnabled: true, databaseEnabled: false, handlesAlerts: true, hasTouchScreen: false, javascriptEnabled: true, locationContextEnabled: true, mobileEmulationEnabled: false, nativeEvents: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: MAC, platformName: MAC, rotatable: false, setWindowRect: true, takesHeapSnapshot: true, takesScreenshot: true, unexpectedAlertBehaviour: , unhandledPromptBehavior: , version: 71.0.3578.98, webStorageEnabled: true}
Session ID: cbff8e41d512f5970d24017a4911ced0
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:214)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:166)
    at org.openqa.selenium.remote.http.JsonHttpResponseCodec.reconstructValue(JsonHttpResponseCodec.java:40)
    at org.openqa.selenium.remote.http.AbstractHttpResponseCodec.decode(AbstractHttpResponseCodec.java:80)
    at org.openqa.selenium.remote.http.AbstractHttpResponseCodec.decode(AbstractHttpResponseCodec.java:44)
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
    at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:609)
    at org.openqa.selenium.remote.RemoteWebDriver$RemoteWebDriverOptions$RemoteWindow.maximize(RemoteWebDriver.java:837)
    at webSearch.openTestSite(webSearch.java:41)
    at webSearch.main(webSearch.java:82)

2 个答案:

答案 0 :(得分:1)

您可以使用以下代码选择所需的选项:

        WebElement query_editbox = driver.findElement(By.id("query"));
        query_editbox.sendKeys("bad");
        String wordToBeSelected = "badge";
        selectOptionFromDropdown(driver, wordToBeSelected);

    private static void selectOptionFromDropdown(WebDriver driver, String wordToBeSelected) {
        WebDriverWait wait=new WebDriverWait(driver,25);
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".autocomplete div")));

        List<WebElement> dropdownList = driver.findElements(By.cssSelector(".autocomplete div"));
        WebElement desiredElement = dropdownList.stream()
                                                .filter(element -> element.getAttribute("title").equals(wordToBeSelected))
                                                .findFirst().get();
        desiredElement.click();
    }

希望这对您有所帮助。

答案 1 :(得分:1)

当您输入一些不可用的单词时,则不会发生自动完成,因此将抛出$users variable。您需要使用try catch块来处理此异常。因此,您的执行将继续进行,而不会出现任何异常。如果您需要在自动完成未发生时添加一些逻辑,则可以在catch块中处理这些逻辑。

如果20秒钟内未显示“自动完成”,则我们可以认为输入的值无效。

请找到修改后的代码:

输入方法

TimeoutException

编辑:解决后续问题

  1. 我在输入单词之前在public void enter(String word) { WebElement query_editbox = driver.findElement(By.id("query")); query_editbox.clear(); query_editbox.sendKeys(word); try{ //AutoComplete is happening even after sending the Enter Key. // So, Value needs to be selected from the autocomplete WebDriverWait wait=new WebDriverWait(driver,20); wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@class='autocomplete']/div"))); List<WebElement> matchedList=driver.findElements(By.xpath("//div[@class='autocomplete']/div")); // System.out.println(matchedList.size()); for(WebElement element : matchedList){ if(element.getText().equalsIgnoreCase(word)){ element.click(); } } }catch (TimeoutException e){ System.out.println("Invalid Word is entered"); } query_editbox.sendKeys(Keys.RETURN); } 方法中添加了clear动作。您可以在main方法中引入一些for循环,以便使用不同的单词执行

    enter

带有数组列表的样本:

String[] input={};

for(int i=0;i<input.length;i++){
    webSrcapper.enter(input[i]);
    webSrcapper.getText();
}
  1. 您可以在不打开浏览器的情况下执行测试,并且可以使用任何一种无头浏览器来完成测试。我建议通过启用以下选项,将Chrome浏览器用作Chrome无头浏览器。

您需要按如下所示修改webSearch类

    ArrayList<String> list=new ArrayList<>();

    list.add("Word1");
    list.add("Word2");
    list.add("Word3");

    for(int i=0;i<input.length;i++){
        webSrcapper.enter(list.get(i));
        webSrcapper.getText();
    }

getText方法:

public class webSearch  {
    public WebDriver driver;

    public webSearch() {
        ChromeOptions options = new ChromeOptions();
        options.addArguments("headless");
        driver=new ChromeDriver(options);
    }