0

The site is https://www.webstaurantstore.com/25887/commercial-gas-ranges.html?page=1 . When I want to localize the search field in the top right corner and send then keys there, it works. But when I want to do the same operation after executing one search it does not work. selenium can locate element, but can not send keys to it. Why something like this happening and how can I avoid that?

while True:
    try:
    a = self.webdriver.find_element_by_xpath('/html/body/div[3]/div[1]/div[2]/div[2]/div/div[2]/div/form/div/input')
    except:
        pass
    else:
        a.send_keys(i.text[1:])
        break

Error:

>>>selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
  (Session info: chrome=81.0.4044.138)
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
Aleksander Ikleiw
  • 2,549
  • 1
  • 8
  • 26
  • this exception is telling you that the DOM has been updated and/or is in the process of updating, so the reference to the webelement is stale (you need to re-find it) since the driver waits for page loads, it's probably a javascript DOM update... a webdriverwait checking for expected condition of presence of element should help. – pcalkins May 27 '20 at 22:38

3 Answers3

0

I believe the problem is the element that you've referred was deleted from the DOM.

That's why you get the exception, the element itself no longer exist even it's showed on UI. You may use try/catch with the same block of instructions.

try:
    line1
    line1
    ...

except:
    line1
    line1
    ...

The is a simple idea to solve the problem like yours, but not the best solution, I will update my answer if I have better than it.

Mahrez BenHamad
  • 1,791
  • 1
  • 15
  • 21
0

poll_frequency-to sleep in between calls and refresh your page if you catch an exception.

 try:
        wait = WebDriverWait(driver, 5, poll_frequency=1)
        a = self.webdriver.find_element_by_xpath('/html/body/div[3]/div[1]/div[2]/div[2]/div/div[2]/div/form/div/input')
        element = wait.until(expected_conditions.visibility_of_element_located(a))
    except:
        driver.refresh()
Amruta
  • 1,128
  • 1
  • 9
  • 19
0

To send a character sequence to the Search box second time after the first search using Selenium you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:

  • CSS_SELECTOR:

    driver.get("https://www.webstaurantstore.com/25887/commercial-gas-ranges.html?page=1")
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='searchval']"))).send_keys("Oven")
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[value='Search']"))).click()
    search = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='searchval']")))
    search.click()
    search.clear()
    search.send_keys("Bowls")
    
  • XPATH:

    driver.get("https://www.webstaurantstore.com/25887/commercial-gas-ranges.html?page=1")
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@name='searchval']"))).send_keys("Oven")
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@value='Search']"))).click()
    search = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@name='searchval']")))
    search.click()
    search.clear()
    search.send_keys("Bowls")
    
  • Note : You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352