【问题标题】:Selenium CSS SelectorSelenium CSS 选择器
【发布时间】:2017-11-28 10:27:47
【问题描述】:

我是硒的新手。我正在尝试使用以下代码在 Stack Overflow 网站上运行一个套件。代码生成 NoSuchElement 异常。 我正在使用带有 Chrome 驱动程序(2.33)的 selenium java 客户端和服务器(3.7.1)。使用 Java 9。在 Windows 10 上。

我已经使用 Chrome 开发者工具上的查找功能验证了 css 选择器。

可能是什么问题?

public class Suite {

    private static final String home = "https://stackoverflow.com";
    private  WebDriver driver = null;

    public static void main(String[] args) {

        Suite suite = new Suite(true);

            suite.login()
                .clickByCSSSelector("a.my-profile");

    }
    public Suite(boolean isHeadLess) {

        ChromeOptions option = new ChromeOptions();
        if (isHeadLess) option.addArguments("--headless");
        System.setProperty("webdriver.chrome.driver", "D:\\work\\webscraping\\chromedriver\\chromedriver.exe");

        driver = new ChromeDriver(option);
    }
    public Suite login() {

        this.navigate(home)
            .setValue("email", "xxxx@gmail.com")
            .setValue("password", "xxxxxx")
            .click("submit-button");
        return this;

    }
    public Suite navigate(String target) {
        driver.navigate().to(target);
        return this;
    }
    public Suite setValue(String elementId, String value) {
        driver.findElement(By.id(elementId)).sendKeys(value);
        return this;
    }
    public Suite clickByXpath(String xpath) {
        this.findByXpath(xpath).click();
        return this;
    }
    public Suite clickByCSSSelector(String selector) {
        this.findByCSSSelector(selector).click();
        return this;
    }   
    private WebElement findByCSSSelector(String selector) {
        return driver.findElement(By.cssSelector(selector));

    }
    public WebElement findByXpath(String xpath) {
        return this.find(By.xpath(xpath));
    }

    public WebElement find(By element) {
        return driver.findElement(element);
    }
    public Suite click(String elementId) {
        this.find(elementId).click();
        return this;
    }
    public WebElement find(String elementId) {
        return this.find(By.id(elementId));
    }

}

例外:

Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"a.my-profile"}
  (Session info: headless chrome=62.0.3202.94)
  (Driver info: chromedriver=2.33.506120 (e3e53437346286c0bc2d2dc9aa4915ba81d9023f),platform=Windows NT 10.0.14393 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 0 milliseconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '3.7.1', revision: '8a0099a', time: '2017-11-06T21:01:39.354Z'
System info: host: 'HMECL000593', ip: '10.0.75.1', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '9'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptSslCerts: true, applicationCacheEnabled: false, browserConnectionEnabled: false, browserName: chrome, chrome: {chromedriverVersion: 2.33.506120 (e3e53437346286..., userDataDir: C:\Users\TOMS~1.VAR\AppData...}, cssSelectorsEnabled: true, databaseEnabled: false, handlesAlerts: true, hasTouchScreen: false, javascriptEnabled: true, locationContextEnabled: true, mobileEmulationEnabled: false, nativeEvents: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: XP, platformName: XP, rotatable: false, setWindowRect: true, takesHeapSnapshot: true, takesScreenshot: true, unexpectedAlertBehaviour: , unhandledPromptBehavior: , version: 62.0.3202.94, webStorageEnabled: true}
Session ID: fa8665d6bf99e34431e27b91ec3a1458
*** Element info: {Using=css selector, value=a.my-profile}
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:488)
    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:164)
    at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:600)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:370)
    at org.openqa.selenium.remote.RemoteWebDriver.findElementByCssSelector(RemoteWebDriver.java:464)
    at org.openqa.selenium.By$ByCssSelector.findElement(By.java:430)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:362)
    at com.tv.webscraping.selenium.SeleniumClient.findByCSSSelector(SeleniumClient.java:81)
    at com.tv.webscraping.selenium.SeleniumClient.clickByCSSSelector(SeleniumClient.java:76)
    at com.tv.webscraping.selenium.Suite.main(Suite.java:19)

Chrome 开发者工具:

【问题讨论】:

  • 点击事件时似乎没有加载 DOM。请稍等片刻。

标签: java selenium web-scraping selenium-chromedriver


【解决方案1】:

您可能还需要在点击前等待

WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);

wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>));

在此处查看有关等待的更多信息:WebDriver - wait for element using Java

如果这不起作用,请尝试以下 xpath,结合上面的等待 .clickByXpath("//a[contains(@class, 'my-profile')]");

下面的一些更多信息来解释 xpath:

  • 多个匹配://div[@class='class' and contains(text(), 'text')]
  • 部分匹配://span[contains(class, 'class')]
  • 开始于://input[starts-with(@name,'input') 这些在处理动态元素时更有用,并且会很健壮。

在此处查看有关 xpath 的更多信息:https://sqa.stackexchange.com/questions/10342/how-to-find-element-using-contains-in-xpath

请注意:我只建议在元素是动态的或没有唯一 ID 时使用 xpaths

此外,您可以使用类名而不是 xpath,我在 c# 中如何执行此操作的示例是 driver.FindElement(By.ClassName("my-profile js-gps-track");

如果以上所有方法都不起作用,您可能需要使用操作,如下所示:

Actions actions = new Actions(driver);
actions.moveToElement(driver.findElement(By.id(id)));
actions.click();
actions.build().perform();

【讨论】:

  • @Vasco 我不得不修改我的答案,现在查看更新版本。
  • 添加等待有帮助。该解决方案适用于当前的 css 选择器。
【解决方案2】:

您还可以在 get(url) 之后添加隐式等待,如下所示。 它适用于所有元素的整个脚本并等待页面加载。 在开始时使用一次隐式等待是一种很好的做法。

driver.get(url); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

试试这个,而不是上面建议的显式等待。 甚至在使用隐式等待之后,如果您得到 ElementNotVisibleException 则为该特定 Web 元素添加显式等待。

但是使用隐式等待通常会帮助您为整个脚本中的所有元素提供加载时间。

希望对你有帮助。

【讨论】:

  • 虽然隐式等待可能会有所帮助,但它们可能会不必要地减慢您的测试速度,我建议您阅读以下seleniumhq.org/docs/04_webdriver_advanced.jsp 并在整个自动化项目中结合使用隐式和显式等待
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-01
  • 2016-07-24
  • 1970-01-01
  • 1970-01-01
  • 2013-09-07
  • 2015-02-04
  • 1970-01-01
相关资源
最近更新 更多