0

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).

tonitone120
  • 1,920
  • 3
  • 8
  • 25

3 Answers3

0

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);''')
Matt Blaha
  • 921
  • 6
  • 9
0

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); 
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
0

try backticks:

document.evaluate(`//div[contains(text(), "'quotes'")]`, ...)
pguardiario
  • 53,827
  • 19
  • 119
  • 159