1

I have this HTML

<div class="callout callout-accordion" style="background-image: url(&quot;/images/expand.png&quot;);">
    <span class="edit" data-pk="bandwidth_bar">Bandwidth Settings</span>
    <span class="telnet-arrow"></span>
</div>

I'm trying to select span with text = Bandwidth Settings, and click on the div with class name = callout.

if driver.find_element_by_tag_name("span") == ("Bandwidth Settings"):
    print "Found"
    time.sleep(100)
    driver.find_element_by_tag_name("div").find_element_by_class_name("callout").click()

print "Not found"
time.sleep(100)

I kept getting

Testing started at 1:59 PM ...
Not found

Process finished with exit code 0

What did I miss?


Select the parent div

    if driver.find_element_by_xpath("//span[text()='Bandwidth Settings']") is None:
        print "Not Found"
    else:
        print "Found"
        span = driver.find_element_by_xpath("//span[text()='Bandwidth Settings']")
        div = span.find_element_by_xpath('..')
        div.click()

I got

WebDriverException: Message: unknown error: Element

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
code-8
  • 54,650
  • 106
  • 352
  • 604

3 Answers3

2

One way would be to use find_element_by_xpath(xpath) like this:

if driver.find_element_by_xpath("//span[contains(.,'Bandwidth Settings')]") is None:
   print "Not found"
else:
   print "Found"
   ...

For an exact match (as you asked for in your comment), use "//span[text()='Bandwidth Settings']"

On your edited question, try one of these:

Locate directly (if there is no other matching element):

driver.find_element_by_css_selector("div[style*='/images/telenet/expand.png']")

Locate via span (provided there isn't any other div on that level):

driver.find_element_by_xpath("//span[contains(.,'Bandwidth Settings')]/../div")
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Würgspaß
  • 4,660
  • 2
  • 25
  • 41
  • How do select the parent div of that ?? – code-8 Feb 16 '17 at 20:24
  • I've tried `driver.find_element_by_css_selector("div.callout").click()` , it click on the first one it found :( – code-8 Feb 16 '17 at 20:25
  • All `find_element`methods are designed to return the _first_ element that matches. So you should use them, if you have a _unique_ locator (or you do not care for the rest of the mathcing elements on page). Alternatively, you can use the `find_elements` methods (notice the plural) which return a list of all matching `WebElement` objects. You can then iterate that list. But I am not so much into python to give you a syntactically correct example right away. – Würgspaß Feb 16 '17 at 20:36
  • I've tried `if driver.find_element_by_xpath("//span[text()='Bandwidth Settings']") is None: print "Not Found" else : print "Found" span = driver.find_element_by_xpath("//span[text()='Bandwidth Settings']") div = span.find_element_by_xpath('..') div.click()` – code-8 Feb 16 '17 at 20:40
  • @Würgspaß, wrong! `span=driver.find_element_...(...)` `span.find_element_...(...)` is correct syntax – Andersson Feb 16 '17 at 21:03
  • From [a comment](https://stackoverflow.com/questions/30002313/selenium-finding-elements-by-class-name-in-python#comment128785684_30025430): *"`find_element_by_*` and `find_elements_by_*` are removed in Selenium 4.3.0. Use `find_element` instead."*. – Peter Mortensen Nov 10 '22 at 19:28
0

The code that you need to use:

from selenium.common.exceptions import NoSuchElementException

try:
    span = driver.find_element_by_xpath('//span[text()="Bandwidth Settings"]')
    print "Found"
except NoSuchElementException:
    print "Not found"

If you need to select the parent div element:

div = span.find_element_by_xpath('./parent::div')
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Andersson
  • 51,635
  • 17
  • 77
  • 129
0

If you have sizzle on the page (jQuery) you can select spans by their text like so:

$("span:contains('Bandwidth Settings')")

Which would be selected like so using the C# bindings:

By.CssSelector("span:contains('Bandwidth Settings')")
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
jacobvoller.com
  • 476
  • 7
  • 28