Reputation: 9
I want to play videos automatically through this page by click the Next bottom. However, at the end of each chapter, there is an exercise page without a video, and I want to skip it.
The skip-to-next-chapter button element is on every page, just not visible.
(1) on exercise page, wait for the page to be loaded
(2) find the skip-to-next-chapter button and click on it
(3) on the video page, skip-to-next-chapter is not visible, so skip this block
However, I can not catch any exceptions, so the process got stuck at the next_ = driver.find_element_by_xpath('//*[foo]')
line. This line doesn’t return anything and run forever. And it won’t throw a Timeout exception.
How can I debug this?
try:
myElem = WebDriverWait(driver, delay).until(EC.presence_of_element_located((By.ID, 'myID')))
next_ = driver.find_element_by_xpath('//*[foo]')
next_.click()
except (NoSuchElementException ,ElementNotVisibleException,TimeoutException):
print('skip this')
changed to
try:
WebDriverWait(driver, 1).until(
EC.element_to_be_clickable((By.XPATH, '//*[contains(concat( " ", @class, " " ), concat( " ", "skip-to-next-chapter", " " ))]'))
).click()
except TimeoutException:
pass
But it still does not work.
Debug final stop point from PyCharm:
When stepping into EC.element_to_be_clickable((By.XPATH, '//*[contains(concat( " ", @class, " " ), concat( " ", "skip-to-next-chapter", " " ))]'))
line, it goes to wait.py >>
def until(self, method, message=''):
"""Calls the method provided with the driver as an argument until the \
return value is not False."""
screen = None
stacktrace = None
end_time = time.time() + self._timeout
while True:
try:
value = method(self._driver)# <<<< stopped here!!
if value:
return value
except self._ignored_exceptions as exc:
screen = getattr(exc, 'screen', None)
stacktrace = getattr(exc, 'stacktrace', None)
time.sleep(self._poll)
if time.time() > end_time:
break
raise TimeoutException(message, screen, stacktrace)
Upvotes: 0
Views: 2467
Reputation: 9
I still don't know what’s wrong with my code. Why doesn’t WebDriver return anything when it can not find the element? Anyway, I walk way from this by another way.
Use Beautiful Soup to parse the page source
Check if the button exists
if exist → driver, click it
if not → skip
src = driver.page_source
soup = BeautifulSoup(src, 'lxml')
next_chap = soup.find('button',class_="btn btn-link skip-to-next-chapter ga")
if(next_chap!=None):
try:
driver.find_element_by_css_selector('.btn.btn-link.skip-to-next-chapter.ga').click()
except Exception as e:
print(e)
else:
print("button not exists ,skip")
Upvotes: 0
Reputation: 193208
You have to take care of a couple of things in your code block. In your code block as you have tried to handle three exceptions and among them NoSuchElementException
and ElementNotVisibleException
looks as a pure overhead to me for the following reasons:
First of all, I am still trying to understand the logic behind waiting for an elementA
(i.e. (By.ID, 'myID')
), but moving ahead and clicking on elementB
, i.e., find_element_by_xpath('//*[foo]')
If your code block is generating NoSuchElementException
, definitely we have to look at the Locator Strategy
which you have adapted if it uniquely identifies an element and also cross-check that the element is within the Viewport
.
If your code block is generating ElementNotVisibleException
, we have to consider this factor as well when we pick up the EC clause, e.g., presence_of_element_located
.
Finally, as moving forward you are attempting to invoke the click()
method on the element, instead of the EC clause as presence_of_element_located
, you should be using element_to_be_clickable(locator)
So to wait
for an element and moving ahead to click
it, your code block will be like:
try:
WebDriverWait(driver, delay).until(EC.element_to_be_clickable((By.ID, 'myID'))).click()
except (TimeoutException):
print('skip this')
Upvotes: 1