pythonselenium-webdriverxpath

A condition on whether an element exists with Python Selenium


I am trying to capture a text from an element which might have two XPaths, but I can't make it happen.

I have tried all of the below methods with no luck and I'm getting this error when running my script once either of the XPath is not found.

Exception has occurred: NoSuchElementException Message: no such element: Unable to locate element:

The target element's XPath can be either the following, and the only difference is the middle div id (7 or 8).

  1. /div/div[2]/div[1]/div[7]/div[2]/span/div/span
  2. /div/div[2]/div[1]/div[8]/div[2]/span/div/span

Appreciate your help and suggestions,

if driver.find_element("xpath",'//*[@id="system"]/div/div[2]/div[1]/div[7]/div[2]/span/div/span'):
    antivirus = driver.find_element("xpath",'//*[@id="system"]/div/div[2]/div[1]/div[7]/div[2]/span/div/span').text        
else:
    antivirus = driver.find_element("xpath",'//*[@id="system"]/div/div[2]/div[1]/div[8]/div[2]/span/div/span').text  
try:
    antivirus = driver.find_element("xpath",'//*[@id="system"]/div/div[2]/div[1]/div[7]/div[2]/span/div/span').text      
except:
     antivirus = driver.find_element("xpath",'//*[@id="system"]/div/div[2]/div[1]/div[8]/div[2]/span/div/span').text
if len(driver.find_element("xpath",'//*[@id="system"]/div/div[2]/div[1]/div[7]/div[2]/span/div/span')) > 0:   
    antivirus = driver.find_element("xpath",'//*[@id="system"]/div/div[2]/div[1]/div[7]/div[2]/span/div/span').text        
else:
    antivirus = driver.find_element("xpath",'//*[@id="system"]/div/div[2]/div[1]/div[8]/div[2]/span/div/span').text  

The HTML part where I'm working on:

<div id="system" class="CardStyled">
<div><div> and more <div>
<div class="ant-row" style="margin-left: -10px; margin-right: -10px; margin-bottom: 2px; row-gap: 0px;"> 

    <div class="ant-col ant-col-12" style="padding-left: 10px; padding-right: 10px;"> 
        <span class="Title--13takrg">Antivirus Product</span> 

    </div> 
    <div class="ant-col ant-col-12" style="padding-left: 10px; padding-right: 10px;"> 

        <span>Windows ATP</span> 
    </div> 
</div> 

Solution

  • You could try using the following single XPath expression to return the span element: (broken into multiple lines for clarity):

    (
       //*[@id="system"]/div/div[2]/div[1]/div[position()=7 or position()=8]
          /div[2]/span/div/span
    )[1]
    

    or equivalently:

    (
       //*[@id="system"]/div/div[2]/div[1]/div[7]/div[2]/span/div/span |
       //*[@id="system"]/div/div[2]/div[1]/div[8]/div[2]/span/div/span
    )[1]
    

    In both the examples, the expression inside the ( and ) will return span elements whose div ancestor was either the 7th or 8th div child of its parent div. Potentially you might get two such span elements; but the final [1] at the end of the expression, outside the ( ... ), will filter the list to return only the first of them.