Search code examples
pythonseleniumselenium-webdrivercss-selectorswebdriver

How to use css selector nth-of-type and nth-child to locate element in Python Selenium


Below is a snippet of how a page is set up.

<class id="class1">
  <ul>
    <li>
      <strong>section 1</strong>
      <a href="link.com/home1">some link 1</a>
    <li>
      <strong>section 2</strong>
      <a href="link.com/home">some link 2</a>
<class id="class1">
  <ul>
    <li>
      <strong>section 3</strong>
      <a href="link.com/home/abc">some link 3</a>
    <li>
      <strong>section 4</strong>
      <a href="link.com/home/def">some link 4</a>

how do i locate link.com/home in section 2?

I figured this would work:

.class1:nth-of-type(1) li:nth-child(2) [href*="/home"]

But it doesn't. It finds the link in section 4 as well. I have to use *= because in different environments the url prefix changes.


Solution

  • For completeness, I have added the </li>, </ul> and </class> tags at the appropriate places and the ideal HTML will be:

    <class id="class1">
      <ul>
        <li>
          <strong>section 1</strong>
          <a href="link.com/home1">some link 1</a>
        </li>
        <li>
          <strong>section 2</strong>
          <a href="link.com/home">some link 2</a>
        </li>
      </ul>
    </class>
    <class id="class1">
      <ul>
        <li>
          <strong>section 3</strong>
          <a href="link.com/home/abc">some link 3</a>
        </li>
        <li>
          <strong>section 4</strong>
          <a href="link.com/home/def">some link 4</a>
        </li>
      </ul>
    </class>
    

    To locate the href attribute of section 2 you can use either of the following Locator Strategies:

    • Using nth-child():

      class#class1 > ul li:nth-child(2) a[href$="home"]
      
    • Using nth-child():

      class#class1 > ul li:nth-of-type(2) a[href$="home"]
      

    Solution

    To print the value of the href attribute you can use either of the following Locator Strategies:

    • Using nth-child():

      print(driver.find_element(By.CSS_SELECTOR, "class#class1 > ul li:nth-child(2) a[href$='home']").get_attribute("href"))
      
    • Using nth-child():

      print(driver.find_element(By.CSS_SELECTOR, "class#class1 > ul li:nth-of-type(2) a[href$='home']").get_attribute("href"))
      

    tl; dr

    What is the difference between p:nth-child(2) and p:nth-of-type(2)?