Reputation: 8757
I'm making a little program which automatically fills out the fast food survey at Del Taco so I can get $1 off my next purchase. I'm using Selenium WebDriver in python for this, and it works beautifully except for one little hiccup where there is one page that sometimes shows up, and sometimes doesn't.
I try to tell whether the extra page shows up with this function here, which is supposed to detect which of the telltale ID's shows up
def whichID(id1, id2):
def find(driver):
if driver.find_element_by_id(id1):
return id1
if driver.find_element_by_id(id2):
return id2
# if neither id is found
return False
try:
print 'waiting'
id = WebDriverWait(driver, timeout).until(find)
print 'done waiting'
return id
except TimeoutException:
print 'timeout exception'
return False
id = whichID("option_745653_340084", "option_522363_247141")
if (id == "option_745653_340084"):
# final page
clickBy('id', "option_745653_340084")
else:
# demographics page
clickBy('id', "option_522363_247141")
clickBy('id', "option_522373_247142")
nextButton.click()
#final page
clickBy('id', "option_745653_340084")
This does work, but any time the extra page (I call it the demographics page) shows up, it takes an extra 5 seconds before it moves on to the final page (I have timeout
set to 5
). I checked it out with some print statements as you can see above, and it looks WebDriverWait
is throwing a TimeoutException
every time the demographics page comes up. I don't understand why. Clearly the IDs are showing up on the page, why would it time out?
For reference, here is the program in it's current iteration
Upvotes: 2
Views: 2658
Reputation: 52685
I think this is the root-cause of your problem:
if driver.find_element_by_id(id1):
return id1
if driver.find_element_by_id(id2):
return id2
return False
It doesn't work as you seem to expect... If driver.find_element_by_id(id1)
doesn't find the element you will not switch to next if
block, but get an exception which will be handled then by except
block. return False
will NEVER be executed.
I would do something like:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
# First option
def whichID(id1, id2):
id_value = None
try:
WebDriverWait(driver, timeout).until(EC.presence_of_element_located((By.ID, id1)))
id_value = id1
except TimeoutException:
try:
WebDriverWait(driver, timeout).until(EC.presence_of_element_located((By.ID, id2)))
id_value = id2
except TimeoutException:
print("No nodes found")
return id_value
# Second option
def whichID(id1, id2):
try:
id_value = WebDriverWait(driver, timeout).until(EC.presence_of_element_located((By.XPATH, "//*[@id='{0}' or @id='{1}']".format(id1, id2)))).get_attribute("id")
return id_value
except TimeoutException:
return None
id_value = whichID("option_745653_340084", "option_522363_247141")
P.S. Note that id()
is a Python built-in function. You shouldn't use "id"
as variable name
Upvotes: 4