В вашем HTML-документе нет '
.Существует '
.
'
только информирует анализатор HTML о вставке одиночной кавычки в дерево документа в этой позиции, на самом деле это не означает, что вы можете искать.
Вы можете сделатьэто:
self.wait_for(lambda: self.assertEqual(
self.browser.find_element_by_xpath(
'//span[contains(text(), "You can\'t have an empty list item")]'
)
)
)
, но это работает только до тех пор, пока кавычки именно так.Когда ваш поисковый текст содержит двойные кавычки, вышеприведенное нарушается, и вы должны избегать вещей наоборот.Это выполнимо, если текст для поиска задан заранее.
Пока получаемый XPath действителен, все готово.В этом случае вышеприведенное приводит к совершенно правильному выражению XPath:
//span[contains(text(), "You can't have an empty list item")]
Но если текст поиска является переменным (например, определяемым пользователем), то все становится волосатым.Python знает escape-последовательности строк, вы всегда можете использовать \"
или \'
, чтобы получить кавычку в строку.XPath не знает такой вещи.
Предположим, что текст для поиска задан как You can't have an "empty" list item
.Это легко сгенерировать с помощью Python, но он не будет работать:
//span[contains(text(), "You can't have an "empty" list item")]
-------------------------------------------^ breaks here
, и этот XPath также не будет работать:
//span[contains(text(), 'You can't have an "empty" list item')]
--------------------------------^ breaks here
и ни один не будет работать, потому что XPathне имеет escape-последовательностей:
//span[contains(text(), 'You can\'t have an "empty" list item')]
---------------------------------^ breaks here
То, что вы можете сделать в XPath, чтобы обойти это, - объединить строки в разных кавычках.Это:
//span[contains(text(), concat('You can', "'" ,'t have an "empty" list item'))]
совершенно корректно и будет искать текст You can't have an "empty" list item
.
И что вы можете сделать в Python, так это создать такую структуру:
- разбить строку поиска на
'
- соединить детали с помощью
', "'", '
- prepend
concat('
, добавить ')
- вставить в выражение XPath
Следующее позволит поиск строки, который никогда не выдаст ошибку времени выполнения из-за неверно сформированного XPath:
search_text = 'You can\'t have an "empty" list item'
concat_expr = "', \"'\", '".join(search_text.split("'"))
concat_expr = "concat('" + concat_expr + "')"
xpath = "//span[contains(text(), %s)]" % concat_expr
xpath
как строковый литерал Python (что выувидит, когда вы распечатаете его на консоль):
'//span[contains(text(), concat(\'You can\', "\'", \'t have an "empty" list item\'))]'
Способ, которым движок XPath видит его (т.е. фактическую строку в памяти):
//span[contains(text(), concat('You can', "'", 't have an "empty" list item'))]
Библиотека lxml позволяет переменным XPath , что намного элегантнее, но я сомневаюсь, что find_elements_by_xpath
в Selenium их поддерживает.