Search code examples
pythonseleniumautomationincrement

XPath increment with Python


I'm trying to increment the variable 'xpath', but it does not work with the code underneath. Does anyone know how I can fix this? If I don't use the function, the inner loop does not work, so I need to keep that part that way (as far as I know).

Any help would be much appreciated! Thanks in advance!

#Function to export data
def loop_function():

    #Search client
    searchCustomerButton = driver.find_element_by_xpath('//*[@id="ibSearchPatient"]')
    searchCustomerButton.click()    

    #Loop client ID's
    followLoop = range(0, 10)
    for x in followLoop:
        xpath = '//*[@id="ctl00_CPH_Main_ctl00_RadGrid_Patienten_ctl00__'
        xpath += str(x)
        xpath += '"]/td[3]'
        
        #Click on cliënt ID
        driver.find_element_by_xpath(xpath).click()

        #Click on Zorgtraject
        zorgtrajectButton = driver.find_element_by_xpath('//*[@id="ctl00_CPH_Top_ToolBar_MenuCurrentPage"]/div/ul/li[3]/a/span/span/span')
        zorgtrajectButton.click()

        #Loop Zorgtraject ID's
        followLoop2 = range(0,10)
        for x in followLoop2:
            try:
                xpath2 = '//*[@id="ctl00_CPH_Main_ctl00_RadGrid1_ctl00__'
                xpath2 += str(x)
                xpath2 += '"]/td[2]'

                #Click on Zorgtraject ID
                driver.find_element_by_xpath(xpath2).click()

                #Dossier button
                dossierButton = driver.find_element_by_xpath('//*[@id="ctl00_CPH_Top_ToolBar_MenuCurrentPage"]/div/ul/li[5]/a/span/span/span')
                dossierButton.click()

                #Dropdown select
                dropdownSelector = driver.find_element_by_xpath('//*[@id="ctl00_CPH_Main_ctl00_Verslagen_radGridBehandelVerloop_ctl00_ctl03_ctl01_PageSizeComboBox_Arrow"]')
                dropdownSelector.click()

                #Prevent not interactable error
                time.sleep(2)

                #Select 50
                selectDropdown = driver.find_element_by_xpath('//*[@id="ctl00_CPH_Main_ctl00_Verslagen_radGridBehandelVerloop_ctl00_ctl03_ctl01_PageSizeComboBox_DropDown"]/div/ul/li[4]')
                selectDropdown.click()

                #Check all documents
                tickDossier = driver.find_element_by_xpath('//*[@id="ctl00_CPH_Main_ctl00_Verslagen_radGridBehandelVerloop_ctl00_ctl02_ctl01_headerChkboxPrint"]')
                tickDossier.click()

                #Click print
                printButton = driver.find_element_by_xpath('//*[@id="ctl00_CPH_Main_ctl00_Verslagen_btnPrintBehandelverloop"]')
                printButton.click()

                #Click on Zorgtraject ID
                zorgtrajectButton2 = driver.find_element_by_xpath('//*[@id="ctl00_CPH_Top_ToolBar_MenuCurrentPage"]/div/ul/li[3]/a/span/span/span')
                zorgtrajectButton2.click()

            #If no Zorgtraject ID, start function over
            except NoSuchElementException:
                loop_function()
                
exec(loop_function())

Solution

  • Have you tried using f-string?

    xpath = f'//*[@id="ctl00_CPH_Main_ctl00_RadGrid_Patienten_ctl00__{x}"]/td[3]'
    

    But, if this pattern is always true, I would prefer using starts-with to find all elements at once, and then loop.

    xpath = '//*[starts-with(@id, "ctl00_CPH_Main_ctl00_RadGrid_Patienten_ctl00__")]'
    

    I guess you could accomplish what you want looping through elements and breaking the second loop when NoSuchElementException:

    # Function to export data
    def loop_function():
        # Search client
        searchCustomerButton = driver.find_element_by_xpath('//*[@id="ibSearchPatient"]')
        searchCustomerButton.click()
    
        # Loop client ID's
        followLoop = range(0, 10)
        for x in followLoop:
            xpath = f'//*[@id="ctl00_CPH_Main_ctl00_RadGrid_Patienten_ctl00__{x}"]/td[3]'
    
            # Click on cliënt ID
            driver.find_element_by_xpath(xpath).click()
    
            # Click on Zorgtraject
            zorgtrajectButton = driver.find_element_by_xpath(
                '//*[@id="ctl00_CPH_Top_ToolBar_MenuCurrentPage"]/div/ul/li[3]/a/span/span/span')
            zorgtrajectButton.click()
    
            # Loop Zorgtraject ID's
            followLoop2 = range(0, 10)
            for x in followLoop2:
                try:
                    xpath2 = f'//*[@id="ctl00_CPH_Main_ctl00_RadGrid1_ctl00__{x}"]/td[2]'
    
                    # Click on Zorgtraject ID
                    driver.find_element_by_xpath(xpath2).click()
    
                    # Dossier button
                    dossierButton = driver.find_element_by_xpath(
                        '//*[@id="ctl00_CPH_Top_ToolBar_MenuCurrentPage"]/div/ul/li[5]/a/span/span/span')
                    dossierButton.click()
    
                    # Dropdown select
                    dropdownSelector = driver.find_element_by_xpath(
                        '//*[@id="ctl00_CPH_Main_ctl00_Verslagen_radGridBehandelVerloop_ctl00_ctl03_ctl01_PageSizeComboBox_Arrow"]')
                    dropdownSelector.click()
    
                    # Prevent not interactable error
                    time.sleep(2)
    
                    # Select 50
                    selectDropdown = driver.find_element_by_xpath(
                        '//*[@id="ctl00_CPH_Main_ctl00_Verslagen_radGridBehandelVerloop_ctl00_ctl03_ctl01_PageSizeComboBox_DropDown"]/div/ul/li[4]')
                    selectDropdown.click()
    
                    # Check all documents
                    tickDossier = driver.find_element_by_xpath(
                        '//*[@id="ctl00_CPH_Main_ctl00_Verslagen_radGridBehandelVerloop_ctl00_ctl02_ctl01_headerChkboxPrint"]')
                    tickDossier.click()
    
                    # Click print
                    printButton = driver.find_element_by_xpath(
                        '//*[@id="ctl00_CPH_Main_ctl00_Verslagen_btnPrintBehandelverloop"]')
                    printButton.click()
    
                    # Click on Zorgtraject ID
                    zorgtrajectButton2 = driver.find_element_by_xpath(
                        '//*[@id="ctl00_CPH_Top_ToolBar_MenuCurrentPage"]/div/ul/li[3]/a/span/span/span')
                    zorgtrajectButton2.click()
    
                # If no Zorgtraject ID, break the inner loop 
                # and continue the outer loop iteration
                except NoSuchElementException:
                    break