Catch errors in all element selectors #8

Merged
mimischi merged 3 commits from patch-1 into master 5 years ago
mimischi commented 5 years ago (Migrated from github.com)
Owner

First of, thanks for the package! I've been planning to write something like this, but never got around doing it.

This PR wraps lines 89-90 in a try..except statement:

56c8a22816/deletefb/deletefb.py (L89-L90)

Without the try..except statement, I was getting the following error:

Traceback (most recent call last):
  File "/Users/mimischi/anaconda3/envs/deletefb/bin/deletefb", line 11, in <module>
    load_entry_point('delete-facebook-posts', 'console_scripts', 'deletefb')()
  File "/Users/mimischi/Code/fb/DeleteFB/deletefb/deletefb.py", line 34, in run_delete
    user_profile_url=args.profile_url)
  File "/Users/mimischi/Code/fb/DeleteFB/deletefb/deletefb.py", line 89, in delete_posts
    menu = driver.find_element_by_css_selector("#globalContainer > div.uiContextualLayerPositioner.uiLayer > div")
  File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 598, in find_element_by_css_selector
    return self.find_element(by=By.CSS_SELECTOR, value=css_selector)
  File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 978, in find_element
    'value': value})['value']
  File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"#globalContainer > div.uiContextualLayerPositioner.uiLayer > div"}
  (Session info: chrome=74.0.3729.157)
  (Driver info: chromedriver=74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29}),platform=Mac OS X 10.14.4 x86_64)
First of, thanks for the package! I've been planning to write something like this, but never got around doing it. This PR wraps lines 89-90 in a `try..except` statement: https://github.com/weskerfoot/DeleteFB/blob/56c8a22816d704c02ff718cd1f835b1316ce373e/deletefb/deletefb.py#L89-L90 Without the `try..except` statement, I was getting the following error: ``` Traceback (most recent call last): File "/Users/mimischi/anaconda3/envs/deletefb/bin/deletefb", line 11, in <module> load_entry_point('delete-facebook-posts', 'console_scripts', 'deletefb')() File "/Users/mimischi/Code/fb/DeleteFB/deletefb/deletefb.py", line 34, in run_delete user_profile_url=args.profile_url) File "/Users/mimischi/Code/fb/DeleteFB/deletefb/deletefb.py", line 89, in delete_posts menu = driver.find_element_by_css_selector("#globalContainer > div.uiContextualLayerPositioner.uiLayer > div") File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 598, in find_element_by_css_selector return self.find_element(by=By.CSS_SELECTOR, value=css_selector) File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 978, in find_element 'value': value})['value'] File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute self.error_handler.check_response(response) File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"#globalContainer > div.uiContextualLayerPositioner.uiLayer > div"} (Session info: chrome=74.0.3729.157) (Driver info: chromedriver=74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29}),platform=Mac OS X 10.14.4 x86_64) ```
mimischi commented 5 years ago (Migrated from github.com)
Poster
Owner

Apparently there is another with the other try..except statement:

Traceback (most recent call last):
  File "/Users/mimischi/Code/fb/DeleteFB/deletefb/deletefb.py", line 97, in delete_posts
    delete_button = menu.find_element_by_xpath("//a[@data-feed-option-name=\"FeedDeleteOption\"]")
  File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 351, in find_element_by_xpath
    return self.find_element(by=By.XPATH, value=xpath)
  File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 659, in find_element
    {"using": by, "value": value})['value']
  File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute
    return self._parent.execute(command, params)
  File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
  (Session info: chrome=74.0.3729.157)
  (Driver info: chromedriver=74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29}),platform=Mac OS X 10.14.4 x86_64)


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/mimischi/anaconda3/envs/deletefb/bin/deletefb", line 11, in <module>
    load_entry_point('delete-facebook-posts', 'console_scripts', 'deletefb')()
  File "/Users/mimischi/Code/fb/DeleteFB/deletefb/deletefb.py", line 34, in run_delete
    user_profile_url=args.profile_url)
  File "/Users/mimischi/Code/fb/DeleteFB/deletefb/deletefb.py", line 101, in delete_posts
    delete_button = menu.find_element_by_xpath("//a[@data-feed-option-name=\"HIDE_FROM_TIMELINE\"]")
  File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 351, in find_element_by_xpath
    return self.find_element(by=By.XPATH, value=xpath)
  File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 659, in find_element
    {"using": by, "value": value})['value']
  File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute
    return self._parent.execute(command, params)
  File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
  (Session info: chrome=74.0.3729.157)
  (Driver info: chromedriver=74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29}),platform=Mac OS X 10.14.4 x86_64)
Apparently there is another with the other `try..except` statement: ``` Traceback (most recent call last): File "/Users/mimischi/Code/fb/DeleteFB/deletefb/deletefb.py", line 97, in delete_posts delete_button = menu.find_element_by_xpath("//a[@data-feed-option-name=\"FeedDeleteOption\"]") File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 351, in find_element_by_xpath return self.find_element(by=By.XPATH, value=xpath) File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 659, in find_element {"using": by, "value": value})['value'] File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute return self._parent.execute(command, params) File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute self.error_handler.check_response(response) File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document (Session info: chrome=74.0.3729.157) (Driver info: chromedriver=74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29}),platform=Mac OS X 10.14.4 x86_64) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/Users/mimischi/anaconda3/envs/deletefb/bin/deletefb", line 11, in <module> load_entry_point('delete-facebook-posts', 'console_scripts', 'deletefb')() File "/Users/mimischi/Code/fb/DeleteFB/deletefb/deletefb.py", line 34, in run_delete user_profile_url=args.profile_url) File "/Users/mimischi/Code/fb/DeleteFB/deletefb/deletefb.py", line 101, in delete_posts delete_button = menu.find_element_by_xpath("//a[@data-feed-option-name=\"HIDE_FROM_TIMELINE\"]") File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 351, in find_element_by_xpath return self.find_element(by=By.XPATH, value=xpath) File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 659, in find_element {"using": by, "value": value})['value'] File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute return self._parent.execute(command, params) File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute self.error_handler.check_response(response) File "/Users/mimischi/anaconda3/envs/deletefb/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document (Session info: chrome=74.0.3729.157) (Driver info: chromedriver=74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29}),platform=Mac OS X 10.14.4 x86_64) ```
mimischi commented 5 years ago (Migrated from github.com)
Poster
Owner

Currently deleting my facebook wall with the following modification:

for _ in range(MAX_POSTS):
        try:
            post_button_sel = "_4xev"
            timeline_element = driver.find_element_by_class_name(post_button_sel)
            actions = ActionChains(driver)
            actions.move_to_element(timeline_element).click().perform()

            menu = driver.find_element_by_css_selector("#globalContainer > div.uiContextualLayerPositioner.uiLayer > div")
            actions.move_to_element(menu).perform()

            try:
                delete_button = menu.find_element_by_xpath("//a[@data-feed-option-name=\"FeedDeleteOption\"]")

            # FIXME Using a bare except here to avoid having to handle all possible exceptions
            except:
                delete_button = menu.find_element_by_xpath("//a[@data-feed-option-name=\"HIDE_FROM_TIMELINE\"]")

            actions.move_to_element(delete_button).click().perform()

            confirmation_button = driver.find_element_by_class_name("layerConfirm")

            # Facebook would not let me get focus on this button without some custom JS
            driver.execute_script("arguments[0].click();", confirmation_button)
        except:
            # Some find_element_by_* method probably threw an error.
            # Do nothing and re-try after refreshing the page.
            pass

        # Required to sleep the thread for a bit after using JS to click this button
        time.sleep(5)
        driver.refresh()

Currently deleting my facebook wall with the following modification: ```python for _ in range(MAX_POSTS): try: post_button_sel = "_4xev" timeline_element = driver.find_element_by_class_name(post_button_sel) actions = ActionChains(driver) actions.move_to_element(timeline_element).click().perform() menu = driver.find_element_by_css_selector("#globalContainer > div.uiContextualLayerPositioner.uiLayer > div") actions.move_to_element(menu).perform() try: delete_button = menu.find_element_by_xpath("//a[@data-feed-option-name=\"FeedDeleteOption\"]") # FIXME Using a bare except here to avoid having to handle all possible exceptions except: delete_button = menu.find_element_by_xpath("//a[@data-feed-option-name=\"HIDE_FROM_TIMELINE\"]") actions.move_to_element(delete_button).click().perform() confirmation_button = driver.find_element_by_class_name("layerConfirm") # Facebook would not let me get focus on this button without some custom JS driver.execute_script("arguments[0].click();", confirmation_button) except: # Some find_element_by_* method probably threw an error. # Do nothing and re-try after refreshing the page. pass # Required to sleep the thread for a bit after using JS to click this button time.sleep(5) driver.refresh() ```
mimischi commented 5 years ago (Migrated from github.com)
Poster
Owner

Updated the PR to contain the new version of the patch.

Updated the PR to contain the new version of the patch.
Nodraak commented 5 years ago (Migrated from github.com)
Owner

Hi,

Bare excepts are discouraged in Python, could you update your PR to use except selenium.common.exceptions.NoSuchElementException: / except selenium.common.exceptions.StaleElementReferenceException: ?

PS: if you are not familiar with the tool pylint, I recomment that you use it to check your code's quality, it's very usefull :)

Thanks

Hi, Bare `except`s are discouraged in Python, could you update your PR to use `except selenium.common.exceptions.NoSuchElementException:` / `except selenium.common.exceptions.StaleElementReferenceException:` ? PS: if you are not familiar with the tool [pylint](https://www.pylint.org/), I recomment that you use it to check your code's quality, it's very usefull :) Thanks
connorskees commented 5 years ago (Migrated from github.com)
Owner

I think the issue is immediately looking for elements after reloading the page, such that the element (menu in the first instance) isn't loaded in time.

I think using explicit waits or just wrapping lines 85-90 in a

while True:
    try:
        foo
    except (NoSuchElementException, StaleElementException):
        continue
    else:
        break

block would be faster since we wouldn't be reloading and sleeping for 5 seconds each time.

I think the issue is immediately looking for elements after reloading the page, such that the element (menu in the first instance) isn't loaded in time. I think using [explicit waits](https://selenium-python.readthedocs.io/waits.html) or just wrapping lines [85](https://github.com/weskerfoot/DeleteFB/blob/56c8a22816d704c02ff718cd1f835b1316ce373e/deletefb/deletefb.py#L85)-[90](https://github.com/weskerfoot/DeleteFB/blob/56c8a22816d704c02ff718cd1f835b1316ce373e/deletefb/deletefb.py#L90) in a ``` while True: try: foo except (NoSuchElementException, StaleElementException): continue else: break ``` block would be faster since we wouldn't be reloading and sleeping for 5 seconds each time.
weskerfoot commented 5 years ago (Migrated from github.com)
Owner

I originally intended to go back and replace the bare try/except with an actual list of exceptions that should be caught.

I originally intended to go back and replace the bare try/except with an actual list of exceptions that should be caught.
weskerfoot commented 5 years ago (Migrated from github.com)
Owner

If you do that, please remove the #FIXME comment as well, thanks.

If you do that, please remove the `#FIXME` comment as well, thanks.
mimischi commented 5 years ago (Migrated from github.com)
Poster
Owner

So should I update this PR to use Connors' proposal (https://github.com/weskerfoot/DeleteFB/pull/8#issuecomment-494338760) with explicit exceptions?

So should I update this PR to use Connors' proposal (https://github.com/weskerfoot/DeleteFB/pull/8#issuecomment-494338760) with explicit exceptions?
weskerfoot commented 5 years ago (Migrated from github.com)
Owner

@mimischi Yes I think it would be a good idea. Thanks!

@mimischi Yes I think it would be a good idea. Thanks!
mimischi commented 5 years ago (Migrated from github.com)
Poster
Owner

Added the explicit exceptions and rebased on current master. I think my current implementation is not 100% what was asked for?

We do need to wrap all element selectors into the try..except statement, as I experienced everyone to fail at some point.

Added the explicit exceptions and rebased on current `master`. I think my current implementation is not 100% what was asked for? We do need to wrap _all_ element selectors into the `try..except` statement, as I experienced everyone to fail at some point.
weskerfoot commented 5 years ago (Migrated from github.com)
Owner

@mimischi I'll test it out today and see

Additionally, if we're wrapping everything in a try/except, then there's no need to have the inner try/except on https://github.com/weskerfoot/DeleteFB/pull/8/files#diff-4da70edc7a5b23e4c4ce8c887686690aR117

Also it might be good to just do something like

selenium_exceptions = (NoSuchElementException, StaleElementReferenceException)

At the top of the module, then you can just do something like

try:
  ...
except selenium_exceptions:
  continue
else:
  break

Which will make it easier to handle more exceptions later.

@mimischi I'll test it out today and see Additionally, if we're wrapping everything in a try/except, then there's no need to have the inner try/except on https://github.com/weskerfoot/DeleteFB/pull/8/files#diff-4da70edc7a5b23e4c4ce8c887686690aR117 Also it might be good to just do something like ``` selenium_exceptions = (NoSuchElementException, StaleElementReferenceException) ``` At the top of the module, then you can just do something like ``` try: ... except selenium_exceptions: continue else: break ``` Which will make it easier to handle more exceptions later.
mimischi commented 5 years ago (Migrated from github.com)
Poster
Owner

I thought the inner try..except is there to hide the post in case it is not-deletable?

Refactored the exceptions. I'll squash the commits as soon as everything is good to go.

I thought the inner `try..except` is there to hide the post in case it is not-deletable? Refactored the exceptions. I'll squash the commits as soon as everything is good to go.
weskerfoot commented 5 years ago (Migrated from github.com)
Owner

@mimischi Oops yes, you're right. I was thinking it wouldn't be necessary anymore. It would be nice if it could do it without the try/except but that's a different feature altogether.

@mimischi Oops yes, you're right. I was thinking it wouldn't be necessary anymore. It would be nice if it could do it without the try/except but that's a different feature altogether.
weskerfoot commented 5 years ago (Migrated from github.com)
Owner

I think this is good, I just want to test it out before merging.

I think this is good, I just want to test it out before merging.
weskerfoot commented 5 years ago (Migrated from github.com)
Owner

Tested it out and it seems to be working well, thanks for the contribution!

Tested it out and it seems to be working well, thanks for the contribution!
The pull request has been merged as 8ec1b2e81f.
Sign in to join this conversation.
No reviewers
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date

No due date set.

Dependencies

This pull request currently doesn't have any dependencies.

Loading…
There is no content yet.