mister-sir
mister-sir

Reputation: 135

Python script runs in console but errors out as a script

I'm working on a script to pull some information from a site that I must login to use. I'm using Python 2.7.12 and Selenium 3.4.3.

#!/usr/bin/python
from selenium import webdriver
browser = webdriver.Firefox(firefox_binary='/usr/bin/firefox', executable_path="./geckodriver")

# Get to the login page
browser.get('https://example.com')
browser.find_element_by_link_text('Application').click()

# Login
browser.find_element_by_id('username').send_keys('notmyusername')
browser.find_element_by_id('password').send_keys('notmypassword')
browser.find_element_by_css_selector('.btn').click()

# Open the application
browser.find_element_by_id('ctl00_Banner1_ModuleList_ctl01_lnkModule').click()

If I copy this code and paste it into the python console, it runs just fine and goes to the page I want. However, when I run the script from the terminal (bash on Linux Mint 18), it errors out. Here's the output with the try and catch statements removed:

Traceback (most recent call last):
  File "./script.py", line 14, in <module>
    browser.find_element_by_id('ctl00_Banner1_ModuleList_ctl01_lnkModule').click()
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 289, in find_element_by_id
    return self.find_element(by=By.ID, value=id_)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 791, in find_element
    'value': value})['value']
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 256, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [id="ctl00_Banner1_ModuleList_ctl01_lnkModule"]

I don't even know how to go about troubleshooting this. Any help?

Upvotes: 4

Views: 198

Answers (2)

mister-sir
mister-sir

Reputation: 135

Per selenium docs, setting browser.implicity_wait(10) # seconds tells the browser to poll the page for 10 seconds before deciding the element isn't there. By default it is set to 0 seconds. Once it is set, the setting persists for the life of the webdriver object.

There are a lot of other nifty tools to wait for elements to load, documented at readthedocs.io.

Upvotes: 1

Thundzz
Thundzz

Reputation: 695

What is most probably happening is that when you run the script from bash, the script runs too quickly and the get_by_id operation is started before the browser has finished loading the page, which results in this error.

As @murali-selenium suggested, you should probably add some wait time before starting to look for stuff in the document.

That can be achived this way:

#!/usr/bin/python
from selenium import webdriver
import time

wait_time_sec = 1

browser = webdriver.Firefox(firefox_binary='/usr/bin/firefox', executable_path="./geckodriver")

# Get to the login page
browser.get('https://example.com')
time.sleep(wait_time_sec)
browser.find_element_by_link_text('Application').click()
time.sleep(wait_time_sec)

# Login
browser.find_element_by_id('username').send_keys('notmyusername')
browser.find_element_by_id('password').send_keys('notmypassword')
browser.find_element_by_css_selector('.btn').click()
time.sleep(wait_time_sec)

# Open the application
try:
    browser.find_element_by_id('ctl00_Banner1_ModuleList_ctl01_lnkModule').click()
except:
    print('failed')

#browser.stop()

Upvotes: 2

Related Questions