pythonseleniumweb-scrapingselenium-chromedriverstaleelementreferenceexception

Selenium error: stale element reference: element is not attached to the page document


i write this code for download image from google from .txt file that has list of strings.

If try with only string into code work.

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(service=Service(r'C:\Users\Desktop\Temp\images\chromedriver.exe'))
driver.get('https://www.google.it/imghp?hl=it&authuser=0&ogbl')

time.sleep(10)

with open("file.txt") as file:
    for row in file.readlines():
        box = driver.find_element("xpath", '/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/input')
        box.send_keys(row)
        box.send_keys(Keys.ENTER)
        time.sleep(3)

        for i in range(1, 3):
            try:
                driver.find_element("xpath", '//*[@id="islrg"]/div[1]/div['+str(i)+']/a[1]/div[1]/img').screenshot(r'C:\Users\Desktop\Temp\images\downloads ('+str(i)+').png')
                time.sleep(3)
            except:
                pass

when execute the script:

but when try to download image the application crash, with this messages:

Traceback (most recent call last):
File "C:\Users\Angelo\Desktop\Temp\images\try.py", line 16, in <module> box.send_keys(Keys.ENTER)
File "C:\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 223, in send_keys self._execute(Command.SEND_KEYS_TO_ELEMENT,
File "C:\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 396, in _execute return self._parent.execute(command, params)
File "C:\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 428, in execute self.error_handler.check_response(response)
File "C:\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 243, 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=105.0.5195.102)
Stacktrace:
Backtrace:
Ordinal0 [0x0076DF13+2219795]
Ordinal0 [0x00702841+1779777]
Ordinal0 [0x0061423D+803389]
Ordinal0 [0x00616D04+814340]
Ordinal0 [0x00616BC2+814018]
Ordinal0 [0x00616E50+814672]
Ordinal0 [0x00643A4B+997963]
Ordinal0 [0x00643B21+998177]
Ordinal0 [0x0063C1D4+967124]
Ordinal0 [0x0065E7FC+1107964]
Ordinal0 [0x006394B4+955572]
Ordinal0 [0x0065EA14+1108500]
Ordinal0 [0x0066F192+1175954]
Ordinal0 [0x0065E616+1107478]
Ordinal0 [0x00637F89+950153]
Ordinal0 [0x00638F56+954198]
GetHandleVerifier [0x00A62CB2+3040210]
GetHandleVerifier [0x00A52BB4+2974420]
GetHandleVerifier [0x00806A0A+565546]
GetHandleVerifier [0x00805680+560544]
Ordinal0 [0x00709A5C+1808988]
Ordinal0 [0x0070E3A8+1827752]
Ordinal0 [0x0070E495+1827989]
Ordinal0 [0x007180A4+1867940]
BaseThreadInitThunk [0x772BFA29+25]
RtlGetAppContainerNamedObjectPath [0x778A7A9E+286]
RtlGetAppContainerNamedObjectPath [0x778A7A6E+238]

UPDATE: file.txt example:

popo
mumu
fiat
bmw
audi

Solution

  • By performing the search, the input element is changing.
    You can use another, better locator to overcome this issue.
    Also, using absolute XPaths or CSS Selectors is never a good idea since these locators are extremally fragile.
    Try this:

    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    import time
    from selenium.webdriver.chrome.service import Service
    from webdriver_manager.chrome import ChromeDriverManager
    
    driver = webdriver.Chrome(service=Service(r'C:\Users\Desktop\Temp\images\chromedriver.exe'))
    driver.get('https://www.google.it/imghp?hl=it&authuser=0&ogbl')
    
    time.sleep(10)
    
    with open("file.txt") as file:
        for row in file.readlines():
            box = driver.find_element("xpath", "//input[@name='q']")
            box.send_keys(row)
            box.send_keys(Keys.ENTER)
            time.sleep(3)
    
            for i in range(1, 3):
                try:
                    driver.find_element("xpath", '//*[@id="islrg"]/div[1]/div['+str(i)+']/a[1]/div[1]/img').screenshot(r'C:\Users\Desktop\Temp\images\downloads ('+str(i)+').png')
                    time.sleep(3)
                except:
                    pass
    

    Also it is always preferably to use WebDriverWait explicit waits, not hardcoded sleeps whenever it is possible.
    UPD
    I have tested the following code and it worked correctly including creating the screenshots

    import time
    
    from selenium import webdriver
    from selenium.webdriver import Keys
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.chrome.options import Options
    
    options = Options()
    options.add_argument("start-maximized")
    
    
    webdriver_service = Service('C:\webdrivers\chromedriver.exe')
    driver = webdriver.Chrome(service=webdriver_service, options=options)
    url = "https://www.google.it/imghp?hl=it&authuser=0&ogbl"
    driver.get(url)
    lines = ["kuku", "mumu", "popo"]
    time.sleep(10)
    
    
    for line in lines:
        box = driver.find_element("xpath", "//input[@name='q']")
        box.clear()
        box.send_keys(line)
        box.send_keys(Keys.ENTER)
        time.sleep(3)
    
        for i in range(1, 3):
            try:
                driver.find_element("xpath", '//*[@id="islrg"]/div[1]/div['+str(i)+']/a[1]/div[1]/img').screenshot(r'C:\Users\****\Desktop\downloads ('+str(i)+').png')
                time.sleep(3)
            except:
                pass