Как построить выражение xpath с переменной для Selenium в python, используя%s
Я пытаюсь использовать селен, чтобы найти и выбрать определенный элемент на основе переменной, переданной в функцию при его вызове. Я думал, что это будет достаточно просто с хорошим ол:
show = browser.find_element_by_xpath("//*[contains(text(), '%s')]" % eventName)
Однако я получаю сообщение об ошибке:
selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: Unable to locate an element with the xpath expression //*[contains(text(), 'VARIABLE_TEXT')] because of the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document': The string '//*[contains(text(), 'VARIABLE_TEXT')]' is not a valid XPath expression.
Вот - искаженная и упрощенная - часть HTML, которую я пытаюсь выбрать:
<ul>
<li class="seriesElement">
<input id="productionId_0" name="productionIds" type="checkbox" value="VALUE"><input type="hidden" name="_productionIds" value="on"><label for="productionId_0" class="prodColor0">TEXT</label>
</li>
<li class="seriesElement">
<input id="productionId_1" name="productionIds" type="checkbox" value="VALUE"><input type="hidden" name="_productionIds" value="on"><label for="productionId_1" class="prodColor1">TEXT</label>
</li>
</ul>
Существует много таких элементов списка, и я хочу выбрать один по тексту. Я просто использовал неправильный синтаксис для своего выражения xpath, или это совершенно другой зверь?
3 ответа
Вы можете попробовать этот способ. Посмотрите, поможет ли это.
VAR_TEXT="TEXT"
print(driver.find_element_by_xpath("//label[contains(text() ,'" + VAR_TEXT + "')]").text)
ИЛИ ЖЕ
VAR_TEXT="TEXT"
print(driver.find_element_by_xpath("//*[contains(text() ,'" + VAR_TEXT + "')]").text)
ИЛИ ЖЕ
VAR_TEXT="TEXT"
print(driver.find_element_by_xpath("//label[text()[contains(.,'" + VAR_TEXT + "')]]").text)
ИЛИ ЖЕ
VAR_TEXT="TEXT"
print(driver.find_element_by_xpath("//*[text()[contains(.,'" + VAR_TEXT + "')]]").text)
Добрый ол %s
работал как положено - вы можете увидеть подстановку в сообщении об ошибке, проблема с самим xpath.
Если вы запустите его через автономный парсер (не браузер), вы увидите виновника ошибки:
Невозможно выполнить операцию XPath. Последовательность из более чем одного элемента недопустима в качестве первого аргумента функции contains () ("", "",...)
(это Java, текст будет похож на другие)
Короче говоря, это результат text()
это беспокоит - это набор узлов; если вы измените эту функцию на .
, он должен работать:
show = browser.find_element_by_xpath("//*[contains(., '%s')]" % eventName)
Чтобы найти определенный элемент на основе его переменного текста, вы можете написать метод следующим образом:
С помощью
.
:def find_myelement_with_text(myString): show = browser.find_element_by_xpath("//label[.='" + myString + "']")
С помощью
%s
:def find_myelement_with_text(myString): show = browser.find_element_by_xpath("//label[contains(text(), '%s')]" % (myString))
С помощью
format()
:def find_myelement_with_text(myString): show = browser.find_element_by_xpath('//label[contains(text(), "{}")]'.format(myString))
Теперь вы можете вызывать этот метод из любой точки вашей программы следующим образом:
find_myelement_with_text("TEXT")