硒FindElement:
driver.FindElement(By.XPath($"//*[contains(text(), '{text}')]"));
投掷:
no such element: Unable to locate element:
{
"method":"xpath",
"selector":"//*[contains(text(), '269424ae-4d74-4a68-91e0-1603f2d674a0')]"
}
(Session info: chrome=74.0.3729.169)
(Driver info:
chromedriver=74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29}),
platform=Linux 4.18.0-20-generic x86_64)
但是它肯定在那里并且xpath有效,因为我可以使用AngleSharp来使用相同的xpath表达式来解析驱动程序的页面源:
new HtmlParser()
.ParseDocument(driver.PageSource)
.SelectSingleNode($"//*[contains(text(), '{text}')]");
目标元素是一个包含guid的div:
<div class="home-project-title-text"> 269424ae-4d74-4a68-91e0-1603f2d674a0 </div>
这是
有趣的是,浏览器控制台中的document.evaluate
也因此xpath表达式而失败。我将其用作运行xpath的辅助函数:
selectSingle = xpath => document.evaluate(xpath, document).iterateNext()
,然后发现它返回null:
> selectSingle("//*[contains(text(), '269424ae-4d74-4a68-91e0-1603f2d674a0')]")
> null
,但绝对存在,并且具有预期的文字,例如我可以使用其他xpath表达式来手动定位并检查其文本内容:
> selectSingle("//*[@id='app']/div/div[1]/div[3]/div/div[1]/div/div[1]/div")
.textContent
.trim()
== "269424ae-4d74-4a68-91e0-1603f2d674a0"
> true
所以原因是创建div的反应是这样的:
React.createElement(
"div",
{className = "home-project-title-text"},
" ",
"269424ae-4d74-4a68-91e0-1603f2d674a0",
" ");
我认为这大致意味着div具有三个textnode作为子节点(是否有效?)。结果看起来100%正常-它呈现完美,并且使用devtools检查元素看起来像是单个文本节点,并且.textContent
返回串联的字符串。
答案 0 :(得分:1)
现在,您提供了更多信息(如何创建此元素):
是的,XML元素可能有几个单独的文本节点作为其子元素。但是,如果文本节点彼此相邻而不是由子元素分隔,则通常不是这种情况。
如果'269424ae-4d74-4a68-91e0-1603f2d674a0'
确实是第二个文本节点,则
//*[contains(text(), '269424ae-4d74-4a68-91e0-1603f2d674a0')]
实际上会不返回此div
元素。您不应将其视为“破坏性的XPath”,只是表达式的确切语义是:
找到一个名称为 first 文本节点包含“ 269424ae-4d74-4a68-91e0-1603f2d674a0”的元素。
text()
实际上选择了元素的所有文本节点,但是诸如contains()
之类的XPath函数仅仅选择第一个文本。
您实际要选择的是
任何名称的元素,其中 any 文本节点包含“ 269424ae-4d74-4a68-91e0-1603f2d674a0”
要完全实现的表达式是:
//*[text()[contains(.,'269424ae-4d74-4a68-91e0-1603f2d674a0')]]
您可以使用一个小的玩具文档来测试这些表情,例如:
<div className="home-project-title-text">
<other/>
269424ae-4d74-4a68-91e0-1603f2d674a0
<other/>
</div>
other
元素迫使div
元素包含三个单独的文本节点,其中两个仅包含空格。
最后,如果您已经知道要查找的元素是div
,则应该专门针对该元素:
//div[text()[contains(.,'269424ae-4d74-4a68-91e0-1603f2d674a0')]]
答案 1 :(得分:0)
该元素可能位于iframe
中,如果是这种情况,则您必须使用IWebDriver.SwitchTo()函数才能尝试切换到所需的iframe定位元素。
可能是该元素无法立即使用的情况,即它是由AJAX request加载的,在这种情况下,您将需要使用WebDriverWait类,以便Selenium可以等到元素在与之交互之前会出现在DOM中。
答案 2 :(得分:0)
尝试以下xpath。看看是否有运气。
//div[@class='home-project-title-text'][contains(.,'269424ae-4d74-4a68-91e0-1603f2d674a0')]
编辑
//div[contains(.,'269424ae-4d74-4a68-91e0-1603f2d674a0')]