Selenium chromedriver 无法定位嵌套的 <li> 标签

Posted

技术标签:

【中文标题】Selenium chromedriver 无法定位嵌套的 <li> 标签【英文标题】:Selenim chrome driver unable to locate nested <li> tags 【发布时间】:2021-01-11 23:03:09 【问题描述】:

我正在尝试查找嵌套的 nl 标记,但我无法从 by.xpath 查询中获取它。

这是我在 java 中的相关代码行。

driver.findElement(By.xpath("//div[@id='navbarNav']/following-sibling::ul[1]/li[2]")).click();

` 我要匹配:

<a class="sub-nav-link style-scope app-shell active" href="#/trend-analysis/tag-search">Trend Analysis

错误:

Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: "method":"xpath","selector":"//div[@id='navbarNav']/following-sibling::ul[1]"
  (Session info: headless chrome=85.0.4183.102)
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '3.14.0', revision: 'aacccce0', time: '2018-08-02T20:13:22.693Z'
System info: host: 'root', ip: '127.0.1.1', os.name: 'Linux', os.arch: 'amd64', os.version: '4.15.0-118-generic', java.version: '1.8.0_265'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities acceptInsecureCerts: false, browserName: chrome, browserVersion: 85.0.4183.102, chrome: chromedriverVersion: 85.0.4183.87 (cd6713ebf92fa..., userDataDir: /tmp/.com.google.Chrome.qnBVf1, goog:chromeOptions: debuggerAddress: localhost:35357, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: LINUX, platformName: LINUX, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: implicit: 0, pageLoad: 300000, script: 30000, unhandledPromptBehavior: dismiss and notify, webauthn:virtualAuthenticators: true
Session ID: 99a0f9193871a6e94151d885c331875d
*** Element info: Using=xpath, value=//div[@id='navbarNav']/following-sibling::ul[1]
        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.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187)
        at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122)
        at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
        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:548)
        at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:322)
        at org.openqa.selenium.remote.RemoteWebDriver.findElementByXPath(RemoteWebDriver.java:424)
        at org.openqa.selenium.By$ByXPath.findElement(By.java:353)
        at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:314)
        at GettingStarted.main(GettingStarted.java:96)

相关 HTML:

<div class="collapse navbar-collapse style-scope app-shell" id="navbarNav">
                <ul class="app-nav navbar-nav mr-auto style-scope app-shell">
                    <li class="nav-item style-scope app-shell">
                        <a class="nav-link p-3 px-4 style-scope app-shell" href="/#/dashboard">Dashboard</a>
                    </li>
                    <li class="nav-item style-scope app-shell">
                        <a class="nav-link py-3 px-4 style-scope app-shell active" href="/#/trend-analysis/tag-search">TrendAnalysis</a>
                        <ul class="sub-nav d-flex flex-row flex-nowrap list-unstyled style-scope app-shell">
                            <li class="sub-nav-item style-scope app-shell">
                                <a class="sub-nav-link style-scope app-shell active" href="#/trend-analysis/tag-search">
                                    Trend Analysis
                                </a>
                            </li>
                            <li class="sub-nav-item style-scope app-shell">
                                <a class="sub-nav-link style-scope app-shell" href="#/trend-analysis/value-based-search">
                                    Value-Based Search
                                </a>
                            </li>
                  .....

我花了整整一周的时间来解决这个问题,但无济于事,请帮助谢谢。

我用

测试了代码
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[@id='navbarNav']/ul")));

driver.findElement(By.xpath("//div[@id='navbarNav']//li/a[contains(@href,'tag-search')]")).click();

更新:

Exception in thread "main" org.openqa.selenium.TimeoutException: Expected condition failed: waiting for element to be clickable: By.xpath: //div[@id='navbarNav']/ul (tried for 30 second(s) with 500 milliseconds interval)
Build info: version: '3.14.0', revision: 'aacccce0', time: '2018-08-02T20:13:22.693Z'
System info: host: 'root', ip: '127.0.1.1', os.name: 'Linux', os.arch: 'amd64', os.version: '4.15.0-118-generic', java.version: '1.8.0_265'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities acceptInsecureCerts: false, browserName: chrome, browserVersion: 85.0.4183.102, chrome: chromedriverVersion: 85.0.4183.87 (cd6713ebf92fa..., userDataDir: /tmp/.com.google.Chrome.7m6LU4, goog:chromeOptions: debuggerAddress: localhost:38779, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: LINUX, platformName: LINUX, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: implicit: 0, pageLoad: 300000, script: 30000, unhandledPromptBehavior: dismiss and notify, webauthn:virtualAuthenticators: true
Session ID: 6e2d32881f709e2e0d727d8cc45813c4
        at org.openqa.selenium.support.ui.WebDriverWait.timeoutException(WebDriverWait.java:113)
        at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:283)
        at GettingStarted.main(GettingStarted.java:103)

更新 2:

当我运行代码时:

driver.findElement(By.xpath("//div[@id='navbarNav']//li/a[contains(@href,'tag-search')]")).click();

我明白了:

Exception in thread "main" org.openqa.selenium.ElementNotInteractableException: element not interactable
  (Session info: headless chrome=85.0.4183.102)

【问题讨论】:

【参考方案1】:

在点击元素之前添加一些等待。

String myElement = "(//div[@id='navbarNav']//li/a[contains(@href,'tag-search')])[1]";    
WebDriverWait wait = new WebDriverWait(driver, 30);
 wait.until(ExpectedConditions.elementToBeClickable(By.xpath(myElement)));

wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(myElement)));

wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(myElement)));

您还需要使用 xpath 定位正确的锚元素。

driver.findElement(By.xpath(myElement)).click()

【讨论】:

我已根据您的建议更新了我的问题。 谢谢,但我遇到了同样的错误waiting for element to be clickable 尝试使用不同的 ExpectedConditions,例如 presentOfElementLocated() Exception in thread "main" org.openqa.selenium.ElementNotInteractableException: element not interactable 另外,另一个问题是tag-search 不是唯一的,因为tag-search 第一次出现在/html/body/app-shell/nav/div/ul[1]/li[2]/a,第二次出现在/html/body/app-shell/nav/div/ul[1]/li[2]/ul/li[1]/a 我相信这就是为什么它不匹配它..我需要限制它首先匹配。【参考方案2】:

检查 Threads.sleep(10),无论那个时间元素是否可点击,如果元素不可点击,则应该是您制作的 xpath 错误。

但如果是点击,则使用 2 并排等待 像这样:

String myElement = "(//div[@id='navbarNav']//li/a[contains(@href,'tag-search')])[1]";    
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(myElement)));
wait.until(ExpectedConditions.elementToBeClickable(By.xpath(myElement)));
driver.findElement(By.xpath(myElement)).click()

【讨论】:

线程“主”org.openqa.selenium.TimeoutException 中的异常:预期条件失败:等待元素可点击:By.xpath: (//div[@id='navbarNav']/ /li/a[contains(@href,'tag-search')])[1](尝试 30 秒,间隔 500 毫秒) 您是否尝试过使用 Threads.sleep 来检查您传递的元素是否单击?@USE【参考方案3】:

对元素上的click(),文本为趋势分析,您可以使用以下任一Locator Strategies:

linkText:

driver.findElement(By.linkText("Trend Analysis")).click();

partialLinkText:

driver.findElement(By.partialLinkText("Trend Analysis")).click();

cssSelector:

driver.findElement(By.cssSelector("div#navbarNav li.sub-nav-item.style-scope.app-shell>a[href$='tag-search']")).click();

xpath:

driver.findElement(By.xpath("//div[@id='navbarNav']//li[@class='sub-nav-item style-scope app-shell']/a[contains(@href, 'tag-search')][contains(., 'Trend Analysis')]")).click();

理想情况下,在需要为elementToBeClickable() 诱导WebDriverWait 的元素上click(),您可以使用以下任一Locator Strategies:

linkText:

new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.linkText("Trend Analysis"))).click();

partialLinkText:

new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.partialLinkText("Trend Analysis"))).click();

cssSelector:

new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("div#navbarNav li.sub-nav-item.style-scope.app-shell>a[href$='tag-search']"))).click();

xpath:

new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//div[@id='navbarNav']//li[@class='sub-nav-item style-scope app-shell']/a[contains(@href, 'tag-search')][contains(., 'Trend Analysis')]"))).click();

【讨论】:

看来,我已经尝试了您上面分享的大部分示例,并且在使用 findElement 函数时,我的代码在 ExpectedConditionsorg.openqa.selenium.ElementNotInteractableException: element not interactable 上都失败了。跨度>

以上是关于Selenium chromedriver 无法定位嵌套的 <li> 标签的主要内容,如果未能解决你的问题,请参考以下文章

基于Selenium和ChromeDriver的自动化页面性能测试

Selenium和PhantomJS 终极最全使用总结

selenium 怎么驱动chromedriver

selenium使用ChromeDriver

Selenium和ChromeDriver的安装与配置

关于python-selenium-chromedriver提示