Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Continue the script if an element is not found using selenium in Python

I am having a trouble trying to figure out how to continue the script if an element is not found using selenium in Python.

This code cycles through reports, finds the refresh button and then clicks on the download the button. The only problem is, that some reports do not have a refresh button. So, I would like the script to continue if the button is not found.

I am still new to python/selenium so that is why I am posting the entire code. I need to know what to slip in to make this work! Thanks in advance for the help with this head banging problem

This is where selenium will try to click the refresh button

browser.find_element_by_css_selector("#ctl00_PlaceHolderMain_ReportViewer1_HtmlOutputReportResults2_updateFilters_TitleAnchor").click()

The complete code:

import time
import os
import os.path
import glob
import shutil
from selenium.webdriver.common.action_chains import ActionChains
from selenium.common.exceptions import MoveTargetOutOfBoundsException
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException

files = glob.glob('/Users/me/Desktop/AUTOREPORTS/*')
for f in files:
    os.remove(f)        

open('/Users/me/Desktop/AUTOREPORTS/report.csv', "w")

for x in range(1, 73):      
    while True:    
        try:
            fp = webdriver.FirefoxProfile('C:/Users/me/Documents/FirefoxProfile')
            browser = webdriver.Firefox(fp)
            browser.get('https://websitething.com/')

            time.sleep(8)

            browser.find_element_by_id("ctl00_PlaceHolderMain_login_UserName").clear()
            browser.find_element_by_id("ctl00_PlaceHolderMain_login_UserName").send_keys("usr")
            browser.find_element_by_id("ctl00_PlaceHolderMain_login_password").clear()
            browser.find_element_by_id("ctl00_PlaceHolderMain_login_password").send_keys("paswd")
            browser.find_element_by_id("ctl00_PlaceHolderMain_login_login").click()

#gets user to reporting front end

            ReportMgr= browser.find_element_by_partial_link_text('Report Manager')
            ReportMgr.click()

            time.sleep(5)

            CustomReport= browser.find_element_by_partial_link_text('Custom Report')
            CustomReport.click()

            time.sleep(5)

            ProgramManagement= browser.find_element_by_partial_link_text('Program Management')
            ProgramManagement.click()
            ProgramManagement= browser.find_element_by_partial_link_text('Program Management').send_keys(Keys.ARROW_LEFT)

#pulls reports

            browser.find_element_by_partial_link_text('Program Management').click()
            time.sleep(60)
            browser.find_element_by_partial_link_text('Program Management').send_keys(Keys.ARROW_DOWN * x, Keys.ENTER)
            time.sleep(60)
            browser.find_element_by_css_selector("#ctl00_PlaceHolderMain_ReportViewer1_HtmlOutputReportResults2_updateFilters_TitleAnchor").click()            
            time.sleep(60)            
            browser.find_element_by_css_selector("#ctl00_PlaceHolderMain_ReportViewer1_HtmlOutputReportResults2_CSVButton_ImageAnchor > img").click()
            fname = "Report(%s).csv" % (x)
            os.chdir('/Users/me/Desktop/AUTOREPORTS')
            time.sleep(60)
            #browser.find_element_by_partial_link_text('Program Management').click()
            #time.sleep(30)
            browser.quit()

        except:
               browser.quit()           
               continue
        else:
               break
like image 497
Yogwhatup Avatar asked Apr 08 '16 15:04

Yogwhatup


1 Answers

Use a try / except block to handle the exception and continue.

try:
    browser.find_element_by_css_selector("#ctl00_PlaceHolderMain_ReportViewer1_HtmlOutputReportResults2_updateFilters_TitleAnchor").click()
except NoSuchElementException:
    # do stuff

Note that Florent B.'s answer will find multiple elements on the page instead of one. So depending on what you need to find, and how many of them there are, it may cause minor performance issues. If you actually need to find multiple elements, his solution will work just fine, but for OP's question best practices dictate that we use the method designed to handle the task at hand instead of the method designed to handle multiples of the same task. It's like greedy matching vs lazy matching with regex. If you only need the first match, write a lazy pattern and it will be more efficient, even if writing the greedy pattern still works out technically.

like image 97
RattleyCooper Avatar answered Nov 10 '22 02:11

RattleyCooper