Как найти точное значение, используя xpath в селеновом веб-драйвере для текста, содержащего & nbsp;?
У меня проблема с выбором точного текста 'Section' из кода с использованием xpath.
** Для ясности, я требую, чтобы точный выбор текста был сделан из innerText или innerHTML элемента, если это возможно, а не из id. **
Я могу использовать функцию содержит текст, но это приводит к тому, что другие частичные совпадения, которые содержат "Раздел", также возвращаются / выделяются:
//div[@aria-hidden='false']//ul/li[contains(text(),'Section')]
Я пытался использовать следующие методы, но я не знаю, правильно ли я синтаксис, так как ничего не возвращается / подсвечивается:
//div[@aria-hidden='false']//ul/li[text()='Section')]
//div[@aria-hidden='false']//ul/li[.='Section']
//div[@aria-hidden='false']//ul/li[normalize-space(.)='Section']
Вот что показано при осмотре узла Section:
<li id="GOS--/40" class="nodecollapsed item parent-node xh-highlight" style="" xpath="1">
Section <span class="child-count"></span>
</li>
Вот что показано в свойствах элемента:
id: "GOS--/40"
innerHTML: "↵ Section <span class="child-count"></span>↵ "
innerText: " Section "
Вот XML, который показывает другие частичные совпадения, которые возвращаются:
<div class="selection-list-dialog modal-dialog Dialog">
<div class="modal-content">
<div class="modal-header SectionHeader">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<span class="modal-title" data-lang="StandardItems">Standard Items</span>
</div>
<div class="modal-body selection-list-container" style="margin-top: 30px" id="base">
<div>
<span data-lang="SelectItemInstructions">Select the items you are interested in from the list.</span>
</div>
<br/>
<div class="pull-left selection-tree-container">
<h4 class="selection-list-title">
<span data-lang="Available">Available</span>
</h4>
<ul class="selection-list selection-tree-list">
<li id="CS--/14" class="nodecollapsed item parent-node">
Country Section <span class="child-count"></span>
</li>
<li id="Sec1--/23" class="nodecollapsed item parent-node">
Section 1 <span class="child-count"></span>
</li>
<li id="Sec2--/24" class="nodecollapsed item parent-node">
Section 2 <span class="child-count"></span>
</li>
<li id="GOS--/40" class="nodecollapsed item parent-node">
Section <span class="child-count"></span>
</li>
<li id="RS--/43" class="nodecollapsed item parent-node">
Regional Section <span class="child-count"></span>
</li>
5 ответов
Это было сложно. Проблема в том, что у вас есть несколько похожих опций, каждый из которых содержит "Раздел", и их трудно отличить друг от друга. Что добавляет к этому то, что каждый из них содержит неразрывный пробел
Который означает, что normalize-space()
не будет работать (напрямую) либо.
Но... Я обнаружил, что ниже XPath будет работать.
//li[normalize-space()='Section\u00a0']
normalize-space()
удаляет пробелы (но не  
) так что вы должны добавить его там с \u00a0
, Я проверил это локально, и это работает.
Попробуйте следовать xpath
посмотрим, поможет ли это.
//li[starts-with(@id,'GOS')][@class='nodecollapsed item parent-node xh-highlight']
ИЛИ ЖЕ
//li[@class='nodecollapsed item parent-node xh-highlight'][@xpath='1']
Вы можете попробовать XPath ниже, чтобы найти узел раздела
Попробуй если поможет
//li[@id='GOS--/40'][contains(text(),'Section')]
Вот метод, который будет получать текст только от родителя. (исключить текст у ребенка (ren))
В Python:
def get_pure_element_text(element):
return driver.execute_script(
"""
var parent = arguments[0];
var child = parent.firstChild;
var textValue = "";
while(child) {
if (child.nodeType === Node.TEXT_NODE)
textValue += child.textContent;
child = child.nextSibling;
}
return textValue;""",
element).strip()
Этот метод будет перебирать все firstChild (прямые потомки) и извлекать весь текст из всех текстовых узлов.
В этом контексте, если вы хотите получить текст li, который имеет идентификатор GOS--/40
затем используйте метод, как показано ниже.
element = driver.find_element_by_xpath("//li[@id='GOS--/40']")
print(get_pure_element_text(element))
Совместное использование этого метода, по крайней мере, может помочь другим (если не OP в этом контексте).
Реализация C#:(не проверено)
string get_pure_text(IWebDriver driver, IWebElement element){
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
return (string)js.ExecuteScript(""""
var parent = arguments[0];
var child = parent.firstChild;
var textValue = "";
while(child) {
if (child.nodeType === Node.TEXT_NODE)
textValue += child.textContent;
child = child.nextSibling;
}
return textValue;""",
element");
Использование:
string output = get_pure_text(driver,element)
Позвольте мне бросить свою шляпу в кольцо....
//li[(normalize-space(text()) = 'Section')]