Home > Blockchain >  How can I click this button with selenium in python? getting error: StaleElementReferenceException
How can I click this button with selenium in python? getting error: StaleElementReferenceException

Time:12-20

error:

Traceback (most recent call last):
  File "C:\Users\m8248\PycharmProjects\pythonProject1-tktopvids\screenshot_comments.py", line 153, in <module>
    print(f"{day.text} = ? {schedule_date.day}")
  File "C:\Users\m8248\PycharmProjects\pythonProject1-tktopvids\venv\lib\site-packages\selenium\webdriver\remote\webelement.py", line 89, in text
    return self._execute(Command.GET_ELEMENT_TEXT)["value"]
  File "C:\Users\m8248\PycharmProjects\pythonProject1-tktopvids\venv\lib\site-packages\selenium\webdriver\remote\webelement.py", line 410, in _execute
    return self._parent.execute(command, params)
  File "C:\Users\m8248\PycharmProjects\pythonProject1-tktopvids\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 444, in execute
    self.error_handler.check_response(response)
  File "C:\Users\m8248\PycharmProjects\pythonProject1-tktopvids\venv\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 249, 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=108.0.5359.125)
Stacktrace:
Backtrace:
    (No symbol) [0x0093F243]
    (No symbol) [0x008C7FD1]
    (No symbol) [0x007BD04D]
    (No symbol) [0x007BFD34]
    (No symbol) [0x007BFBE5]
    (No symbol) [0x007BFE80]
    (No symbol) [0x007E7D27]
    (No symbol) [0x0080858C]
    (No symbol) [0x007E2BFF]
    (No symbol) [0x00808804]
    (No symbol) [0x0081C9EB]
    (No symbol) [0x00808386]
    (No symbol) [0x007E163C]
    (No symbol) [0x007E269D]
    GetHandleVerifier [0x00BD9A22 2655074]
    GetHandleVerifier [0x00BCCA24 2601828]
    GetHandleVerifier [0x009E8C0A 619850]
    GetHandleVerifier [0x009E7830 614768]
    (No symbol) [0x008D05FC]
    (No symbol) [0x008D5968]
    (No symbol) [0x008D5A55]
    (No symbol) [0x008E051B]
    BaseThreadInitThunk [0x75C400F9 25]
    RtlGetAppContainerNamedObjectPath [0x77377BBE 286]
    RtlGetAppContainerNamedObjectPath [0x77377B8E 238]


Process finished with exit code 1

code:

delay()

days = driver.find_elements(By.CSS_SELECTOR, ".jsx-1929600011.day")
for day in days:
    print(f"{day.text} = ? {schedule_date.day}")
    if day.text == str(schedule_date.day):
        print("yes day match clicking")
        day.click()
delay()

I expect it to click on the day in the calendar (calendar is still on the page when error occurs).

The button I'm trying to click is on tiktok.com/upload > schedule video > any day (specifically 25 in this case).

I am switching to the iframe, uploading the video works, changing the caption works, switching the schedule video button works, switching between months works, but I get this error trying to click the day icon.

CodePudding user response:

Looks like by performing day.click() the elements on the page are got refreshed, this causes to all previously collected web elements (that are actually just a references to the physical web elements on the page) to become Stale as descried here and in many other places.
What you can do is to collect the list of web elements days again.
So, this should work:

days = driver.find_elements(By.CSS_SELECTOR, ".jsx-1929600011.day")
for day in days:
    print(f"{day.text} = ? {schedule_date.day}")
    if day.text == str(schedule_date.day):
        print("yes day match clicking")
        day.click()
        time.sleep(2)
        days = driver.find_elements(By.CSS_SELECTOR, ".jsx-1929600011.day")

CodePudding user response:

I don't really know python, but I know Selenium. I'll see what I can do to help.

So, by finding and interacting with an element, Javascript events happen in the background. Some websites have this problem more than others, and different handling is required for each, but here is some semi-pseudo code for a method that will handle stale elements.

HandleStaleElement(int tries)
    if (tries < 1)
        raise Exception("Element is stale")
    elements = driver.find_elements()
    for element in elements:
        try:
            element.click()
        except:
            UpdateJsEvents(element)
            HandleStaleElement(tries - 1)

UpdateJsEvents(element)
    string attributes = element.GetAttribute("outerHTML")
    if (attributes.contains("onchange"))
        driver.execute_script("arguments[0].onchange()", element)
    if (attributes.contains("onblur"))
        driver.execute_script("arguments[0].onblur()", element)
    driver.execute_script("arguments[0].blur()", element)
  • Related