My challenge is to locate an element by its content which contains single-quotes. I do this successfully with vanilla JS here:
singleQuotes = document.evaluate("//div[contains(text(), \"'quotes'\")]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
singleQuotes = singleQuotes.snapshotItem(0);
console.log(singleQuotes)
<div>'quotes'</div>
However, when I use Python & Selenium to implement the same vanilla JS, the Xpath is invalid:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
window = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
window.get("www.someurl.com")
window.execute_script(f'''xpath = document.evaluate("//div[contains(text(), \\"'quotes'\\")]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);''')
I get a SyntaxError: Failed to execute 'evaluate' on 'Document': The string...is not a valid XPath expression.
(I would try & show this in a sandbox but I don't know how to).
CodePudding user response:
I believe it's just the " getting eaten by python. Use a double \\.
Forget selenium and compare:
print(f'''xpath = document.evaluate("//div[contains(text(), \"'quotes'\")]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);''')
and
print(f'''xpath = document.evaluate("//div[contains(text(), \\"'quotes'\\")]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);''')
CodePudding user response:
This error message...
SyntaxError: Failed to execute 'evaluate' on 'Document': The string...is not a valid XPath expression
...implies that the xpath based locator strategy you have constructed was not a valid locator.
Solution
You can use either of the locator strategy:
Using the complete text
'quotes'
singleQuotes = document.evaluate("//div[text()=\"'quotes'\"]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
Using partial text
quotes
singleQuotes = document.evaluate("//div[contains(., 'quotes')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);