Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
73 views
in Technique[技术] by (71.8m points)

python - selenium.common.exceptions.InvalidSelectorException with "span:contains('string')"

I am working on selenium python in firefox. I am trying to find element by css selector

element = "span:contains('Control panel')"
my_driver.find_element_by_css_selector(element)

I am getting below error

 raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.InvalidSelectorException: Message: Given css selector expression "span:contains('Control panel')" is invalid: InvalidSelectorError: 'span:contains('Control panel')' is not a valid selector: "span:contains('Control panel')"

In selenium IDE I am successfully able to find element by this field but in Python it is not working

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The error says it all :

selenium.common.exceptions.InvalidSelectorException: Message: Given css selector expression "span:contains('Control panel')" is invalid: InvalidSelectorError: 'span:contains('Control panel')' is not a valid selector: "span:contains('Control panel')"

As per Issue#987 and Issue#1547:

The :contains pseudo-class isn't in the CSS Spec and is not supported by either Firefox or Chrome (even outside WebDriver).

The pseudo-class was specific to the Sizzle Selector Engine that Selenium 1.0 relied on. But, it was decided that WebDriver was not going to support the Sizzle style CSS selectors that Selenium 1.0 used.

Now, an interesting fact is the :contains pseudo-class will work for browsers that don't natively support CSS selectors (IE7, IE8, etc) which causes inconsistencies between browsers and selectors.

Hence a better solution would have been to go with any other attribute of the <span> tag as follows :

element = "span[attribute_name=attribute_value]"

Alternate Solution

You can use either of the following xpaths as per the prevailing DOM Tree:

  • Using text():

    element = my_driver.find_element_by_xpath("//span[text()='Control panel']")
    
  • Using contains():

    element = my_driver.find_element_by_xpath("//span[contains(.,'Control panel')]")
    
  • Using normalize-space():

    element = my_driver.find_element_by_xpath("//span[normalize-space()='Control panel']")
    

Using jQuery

You can also use jQuery as follows:

$('span:contains("Control panel")')

Trivia :

A valuable comment from @FlorentB.

CSS selector is not supported by the console either, but JQuery supports it. The $('...') from the console is a shorthand for document.querySelector which is generally overridden with JQuery when the page has it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...